2013-02-14 36 views
5

मैं सबसे प्रभावी पंक्तियों को खोजने के लिए क्वेरी लिखना चाहता हूं। मैं इन तालिकाओं है:सबसे प्रभावी डेटा खोजने के लिए एसक्यूएल क्वेरी

Sellers 
Id Name 
1 Mark 
2 Julia 
3 Peter 

Stocks 
Id SellerId ProductCode StockCount 
1  1   30A   10 
2  2   20A    4 
3  1   20A    2 
4  3   42B    3 

और वहाँ sqlfiddle http://sqlfiddle.com/#!6/fe5b1/1/0

मेरे आशय शेयर के लिए अधिकतम विक्रेता पाते हैं।

यदि ग्राहक 30 ए, 20 ए और 42 बी उत्पादों को चाहते हैं। मुझे "मार्क" और "पीटर" पर लौटने की ज़रूरत है क्योंकि मार्क के पास उत्पाद (30 ए और 20 ए) है, इसलिए जूलिया की आवश्यकता नहीं है।

मैं इसे एसक्यूएल में कैसे हल कर सकता हूं?

+1

कौन सा आरडीबीएमएस को कोड ऊपर बदलने के प्रयोग कर रहे हैं, एमएस एसक्यूएल सर्वर, MySQL, PostgreSQL ...? मुझे लगता है कि एमएस एसक्यूएल सर्वर एसक्यूएल फिडल इसका उपयोग कर रहा है। आवश्यक टैग जोड़ें। और आपके द्वारा जोड़ा गया एसक्यूएल फिडल लिंक, अपने प्रश्न को बेहतर तरीके से संपादित करें और इसे वहां जोड़ें, इसलिए प्रश्न देखने वाले अन्य उपयोगकर्ताओं को यह सुनिश्चित करने के लिए सभी टिप्पणियों को देखने की आवश्यकता नहीं है कि उनके पास सभी जानकारी – Yaroslav

+1

है, मुझे लगता है कि यहां समस्या ओज़ान है आदेश की पूर्ति करने वाले न्यूनतम आपूर्तिकर्ताओं को ढूंढना चाहता है। आप संभवतः आपूर्तिकर्ताओं की सूची को उन वस्तुओं की कुल संख्या से ऑर्डर करना चाहते हैं, जिन्हें वे आपूर्ति कर सकते हैं, हालांकि कोडिंग मुश्किल हो सकती है। – bendataclear

+0

मुझे लगता है कि आपकी समस्या यहां वर्णित है तो यहां वर्णित है। क्या होगा यदि दोनों विक्रेताओं के पास समान मात्रा में उत्पाद हों (लेकिन विभिन्न उत्पाद?) –

उत्तर

3

यह अस्थायी तालिकाओं

की मदद से काम करने के लिए मिल गया
SELECT 
    s.SellerId, 
    ProductList = STUFF((
         SELECT ',' + ProductCode FROM Stocks 
         WHERE s.SellerId = Stocks.SellerId 
         ORDER BY ProductCode FOR XML PATH('') 
         ) 
         , 1, 1, ''), COUNT(*) AS numberOfProducts 
INTO #tmptable 
FROM 
    Stocks s 
WHERE 
    s.ProductCode IN ('30A','20A','42B') 
    AND s.StockData > 0 
GROUP BY s.SellerId; 

/*this second temp table is necessary, so we can delete from one of them*/ 
SELECT * INTO #tmptable2 FROM #tmptable; 

DELETE t1 FROM #tmptable t1 
WHERE EXISTS (SELECT 1 FROM #tmptable2 t2 
       WHERE t1.SellerId != t2.SellerId 
       AND t2.ProductList LIKE '%' + t1.ProductList + '%' 
       AND t2.numberOfProducts > t1.numberOfProducts) 
; 

SELECT Name FROM #tmptable t INNER JOIN Sellers ON t.SellerId = Sellers.Id; 

अद्यतन:

CREATE TABLE tmptable (SellerId int, ProductList nvarchar(max), numberOfProducts int); 

tmpTable2 के लिए एक ही:

कृपया स्थिर तालिकाओं के साथ एक कोशिश की है। तब

INSERT INTO tmpTable 
SELECT 
    s.SellerId, 
    ProductList = STUFF((
         SELECT ',' + ProductCode FROM Stocks 
         WHERE s.SellerId = Stocks.SellerId 
         ORDER BY ProductCode FOR XML PATH('') 
         ) 
         , 1, 1, ''), COUNT(*) AS numberOfProducts 
FROM 
    Stocks s 
WHERE 
    s.ProductCode IN ('30A','20A','42B') 
    AND s.StockData > 0 
GROUP BY s.SellerId; 

INSERT INTO tmpTable2 SELECT * FROM tmpTable; 

DELETE t1 FROM tmptable t1 
WHERE EXISTS (SELECT 1 FROM tmptable2 t2 
       WHERE t1.SellerId != t2.SellerId 
       AND t2.ProductList LIKE '%' + t1.ProductList + '%' 
       AND t2.numberOfProducts > t1.numberOfProducts) 
; 

SELECT * FROM tmpTable; 
DROP TABLE tmpTable, tmpTable2; 
+0

धन्यवाद! आप आदमी हो ! – OzanWt

+0

एक प्रश्न, जैसे क्वेरी वास्तविक डेटा में सच नहीं है। यह सभी उत्पादों को वापस कर देता है, इसलिए वास्तविक डेटा में प्राप्य से क्वेरी कैंट डिलीट मौजूद नहीं है, हमारे उत्पाद सूची मूल्य उदाहरण के लिए 1000 वर्ण की लंबाई के लिए कभी-कभी बहुत लंबा होता है, तो क्या यह आपकी राय के लिए कारण है या नहीं? – OzanWt

+0

मुझे समस्या को समझने में परेशानी हो रही है। क्या आपको एक त्रुटि मिल रही है कि अस्थायी तालिका की तरह कुछ अस्थायी तालिका होने के लिए बहुत बड़ा है? यदि हां, तो temp तालिका नाम के सामने '#' को हटा दें और जब आपको उनकी आवश्यकता नहीं है तब टेबल को छोड़ दें। – fancyPants

-2

मुझे लगता है कि यह हो सकता है कि आप क्या देख रहे हैं?

Select name,sum(stockdata) as stockdata from sellers s1 join Stocks s2 on s1.id=s2.sellerid 
where ProductCode in ('30A','20A','42B') 
group by name 
order by sum(stockdata) desc 

मुझे आशा है कि इससे मदद मिलती है।

यदि आप केवल शीर्ष 2 पीपीएल चाहते हैं। आप लिखना

Select top 2 name,sum(stockdata) as stockdata from sellers s1 join Stocks s2 on s1.id=s2.sellerid 
where ProductCode in ('30A','20A','42B') 
group by name 
order by sum(stockdata) desc 

मुझे लगता है कि यह आपके लिए क्या देख रहे हैं, क्योंकि मैं इसे कैसे देखते हैं, तो आप दो लोग हैं, जो उच्चतम stockdata है का चयन करना चाहते हैं?

+2

नहीं, यह नहीं है, वह क्या देख रहा है। वह सिर्फ जूलिया नहीं चाहता क्योंकि मार्क के पास उसका उत्पाद और दूसरा है, इसलिए मार्क अधिक "प्रभावी" है। – fancyPants

+0

@ टॉम्बॉम हाँ, आपने सही कहा। – OzanWt

+0

आह, हेहे इसके बारे में खेद है :) – Joe