2012-02-01 13 views
6

तालिका में 'Sales_Order_ID', 'Sales_Order_Line_Number', और 'Sales_Order_Line_staus' अन्य फ़ील्ड के बीच है। मैं 'Sales_Order_ID' को पुनर्प्राप्त करना चाहता हूं, जहां 'Sales_Order_ID' के लिए प्रत्येक रिकॉर्ड समान 'Sales_Order_Line_Status' है।मैं बिक्री आदेश कैसे प्राप्त करूं जहां बिक्री आदेश की प्रत्येक पंक्ति बंद है?

तो, यदि बिक्री आदेश एक्स के लिए प्रत्येक रिकॉर्ड में 'बंद' की स्थिति है, तो मैं इसे पुनर्प्राप्त करना चाहता हूं। यदि बिक्री आदेश वाई में स्थिति के साथ तीन रिकॉर्ड हैं और 'ओपन' स्थिति वाला एक रिकॉर्ड है, तो मैं इसे पुनर्प्राप्त नहीं करना चाहता हूं।

मैंने कोशिश की:

SELECT DISTINCT s1.so_ID, s1.SO_line_status 
FROM sales_order_table s1 
INNER JOIN sales_order_table s2 
ON s1.so_id = s2.so_id 
    AND s1.so_line_status = s2.so_line_status 
ORDER BY s1.so_id 

कोई सफलता के लिए। कोई सफलता के लिए

SELECT DISTINCT s1.so_ID, s1.SO_line_status 
FROM sales_order_table s1 
INNER JOIN sales_order_table s2 
ON s1.so_id = s2.so_id 
    AND NOT s1.so_line_status <> s2.so_line_status 
ORDER BY s1.so_id 

:

SELECT DISTINCT s1.so_ID, s1.SO_line_status 
FROM sales_order_table s1 
INNER JOIN sales_order_table s2 
ON s1.so_id = s2.so_id 
    AND s1.so_line_status <> s2.so_line_status 
ORDER BY s1.so_id 

तो मैं करने की कोशिश की: निम्नलिखित जो मैं चाहता के विपरीत देने के लिए लगता है।

तब मैं पूरी तरह से नोब चला गया और उम्मीद कर रहा था कि यह काम करेगा। क्या मैं यहां बंद हूं या पूरी तरह गलत तरीके से जा रहा हूं?

इसके अलावा, मुझे एहसास है कि उपर्युक्त प्रश्न परिणामों को 'बंद' स्थिति तक सीमित नहीं करते हैं, लेकिन मुझे लगा कि अगर मैं केवल एक ही स्थिति रेखाएं लौटा सकता हूं, तो मैं उन्हें 'बंद' तक सीमित कर सकता हूं।

क्षमा करें अगर यह अस्पष्ट है! यदि ऐसा है, तो मैं स्पष्टीकरण देने की कोशिश करूंगा।

उत्तर

5
SELECT so_ID 
FROM sales_order_table 
GROUP BY so_ID 
HAVING MAX(SO_line_status) = 'Closed' AND 
     MIN(SO_line_status) = 'Closed' AND 
     COUNT(CASE WHEN SO_line_status IS NULL THEN 1 END) = 0 

तुम भी इस्तेमाल कर सकते हैं EXCEPT अपने आरडीबीएमएस यह समर्थन करता है तो

SELECT so_ID 
FROM sales_order_table 
WHERE SO_line_status = 'Closed' 
EXCEPT 
SELECT so_ID 
FROM sales_order_table 
WHERE SO_line_status IS NULL OR SO_line_status <> 'Closed' 
+0

संभावित बढ़त का मामला: यदि किसी दिए गए 'so_ID' के लिए एक या अधिक पंक्तियों में एक पूर्ण 'SO_line_status' है और शेष' बंद 'हैं, तो' so_ID' गलत तरीके से वापस कर दिया जाएगा क्योंकि कुल कार्य NULLs अनदेखा करें। –

+0

'हैविंग MAX (SO_line_status) = MIN (SO_line_status)' जैसे कुछ के बारे में कैसे? –

+0

@MarcusAdams - क्योंकि ओपी विशेष रूप से बंद स्थिति में रूचि रखता है। "मुझे लगा कि अगर मैं एक ऐसा प्राप्त कर सकता हूं जो केवल वही स्थिति रेखाएं लौटाता है, तो मैं उन्हें 'बंद' तक सीमित कर सकता हूं।" –

2

यहां मूल दृष्टिकोण आईडी और स्थिति द्वारा समूहित करना है। यदि उस समूह की गिनती केवल आईडी द्वारा गणना के बराबर है, तो आपको पता चलेगा कि सभी पंक्तियों में समान स्थिति है।

SELECT s1.so_ID, s1.SO_line_status 
    FROM sales_order_table s1 
    GROUP BY s1.so_ID, s1.SO_Line_status 
    HAVING COUNT(*) = (SELECT COUNT(*) 
          FROM sales_order_table s2 
          WHERE s2.so_ID = s1.so_ID) 

सिर्फ 'बंद' की स्थिति में उसे संक्षिप्त करने के लिए बस एक कहां खंड जोड़ें:

SELECT s1.so_ID, s1.SO_line_status 
    FROM sales_order_table s1 
    WHERE s1.SO_line_status = 'closed' 
    GROUP BY s1.so_ID, s1.SO_Line_status 
    HAVING COUNT(*) = (SELECT COUNT(*) 
          FROM sales_order_table s2 
          WHERE s2.so_ID = s1.so_ID) 
2

Joe's approach निश्चित रूप से काम करना चाहिए। यहां कुछ विकल्प हैं (जो अधिक अनुकूलन योग्य हो सकते हैं या नहीं भी हो सकते हैं):

समस्या को घुमाएं, ओपन की स्थिति वाले लोगों को फ़िल्टर करने के लिए (या बंद करें, आपके पास कितनी स्थितियों के आधार पर):

SELECT T1.Id 
FROM Table as T1 
LEFT JOIN (SELECT Id FROM Table WHERE Status <> 'Closed') as T2 ON 
    T1.Id = T2.Id 
WHERE T2.Id IS NULL 

मैक्स और मिन उपयोग समूहीकरण कार्यों के रूप में: 2 व्युत्पन्न टेबल

SELECT Id 
FROM Table 
GROUP BY Id, Status 
HAVING MAX(Status) = 'Closed' 

उपयोग:

SELECT C.Id 
FROM (
    SELECT Id FROM Table WHERE Status = 'Closed' 
) as C 
LEFT JOIN (
    SELECT Id FROM Table WHERE Status = 'Open' 
) as O ON 
    C.Id = O.Id 
WHERE O.Id IS NULL 

मुझे संदेह होगा कि 2 LEFT JOIN दृष्टिकोण MAX संस्करणों और उसके बाद COUNT के बाद सबसे अच्छा अनुकूलन करेंगे, लेकिन यदि प्रदर्शन आपके लिए महत्वपूर्ण है तो आपको निश्चित रूप से प्रोफ़ाइल करना चाहिए। अनुपस्थित प्रदर्शन विचार, मैं व्यक्तिगत रूप से 2 व्युत्पन्न तालिकाओं को सबसे अधिक पठनीय पाते हैं - अन्य असहमत हो सकते हैं।सादे अंग्रेजी में

SELECT DISTINCT Sales_Order_ID 
FROM sales_order_table t1 
WHERE 
    'Closed' = ALL (
     SELECT Sales_Order_Line_Staus 
     FROM sales_order_table t2 
     WHERE t1.sales_order_id = t2.sales_order_id 
    ) 

:

1

आप सभी ऑपरेटर का उपयोग कर सकते हैं का चयन करें उन Sales_Order_ID रों जिसके लिए संबंधित पंक्तियों के सभी एक ही स्थिति है, और कहा कि स्थिति होता है 'बंद' करने के लिए।


आप चाहते हैं किसी भी स्थिति, आप आसानी से यह कर सकते हैं ...

SELECT DISTINCT Sales_Order_ID, Sales_Order_Line_Staus 
FROM sales_order_table t1 
WHERE 
    Sales_Order_Line_Staus = ALL (
     SELECT Sales_Order_Line_Staus 
     FROM sales_order_table t2 
     WHERE t1.sales_order_id = t2.sales_order_id 
    ) 

... या यहाँ तक कि इस (आप वास्तविक Sales_Order_Line_Staus में कोई दिलचस्पी नहीं कर रहे हैं):

SELECT Sales_Order_ID 
FROM sales_order_table 
GROUP BY Sales_Order_ID 
HAVING COUNT(DISTINCT Sales_Order_Line_Staus) = 1 
संबंधित मुद्दे