SQL

2012-05-10 14 views
7

में "खाली" कुल परिणाम कैसे उत्पन्न करें I मेरी रिपोर्ट को बेहतर बनाने के लिए एक SQL क्वेरी को परिष्कृत करने का प्रयास कर रहा हूं। मेरी क्वेरी कुछ तालिकाओं से समूह, कुछ कॉलम से समूह पढ़ती है और कुछ समेकित क्षेत्रों (गणना और रकम) की गणना करती है।SQL

SELECT A, B, C, COUNT(*), SUM(D) FROM T 
GROUP BY A, B, C 
ORDER BY A, B, C 

अब, चलो मान बी और सी स्तंभों कुछ परिभाषित लगातार तार हैं, उदाहरण के लिए, बी हो सकता है 'B1' या 'B2', सी 'C1' या 'C2' हो सकता है। तो, एक उदाहरण resultset है:

A | B | C | COUNT(*) | SUM(D) 
-------------------------------- 
A1 | B1 | C1 |  34 | 1752 
A1 | B1 | C2 |  4 | 183 
A1 | B2 | C1 |  199 | 8926 
A1 | B2 | C2 |  56 | 2511 
A2 | B1 | C2 |  6 |  89 
A2 | B2 | C2 |  12 | 231 
A3 | B1 | C1 |  89 | 552 
... 

आप देख सकते हैं, 'A1' के लिए मैं सभी चार संभावित (बी, सी) संयोजन है, लेकिन वह 'A2' के लिए सच नहीं है। मेरा सवाल है: मैं (बी, सी) संयोजन के लिए सारांश पंक्तियों को वास्तव में प्रस्तुत तालिका में कैसे प्रस्तुत कर सकता हूं? यही कारण है, मैं कैसे मुद्रित कर सकते हैं, उदाहरण के लिए, यह भी इन पंक्तियों:

A | B | C | COUNT(*) | SUM(D) 
-------------------------------- 
A2 | B1 | C1 |  0 |  0 
A2 | B2 | C1 |  0 |  0 

एकमात्र समाधान मैं देख सकता हूँ मान सभी (बी, सी) के साथ कुछ auxiliarity टेबल बना और फिर एक सही बाहरी के साथ शामिल हों बनाना है वह ऑक्स टेबल। लेकिन मैं एक क्लीनर रास्ता खोज रहा हूं ...

सभी को धन्यवाद।

+0

आप mssql, oracel, mysql का उपयोग कर रहे हैं? – Arion

+0

ओरेकल। लेकिन इस समय, प्रश्न एक मानक तरीके से लिखा गया है (यह MySQL पर भी चलता है, हमारे पास डीबी की एक MySQL प्रतिलिपि नहीं है, कोई प्रश्न-प्रासंगिक कारण नहीं है)। –

+0

शायद [यह] (http://www.techrepublic.com/article/group-by-grouping-sets-for-custom-rollups-in-oracle/6134424) मदद करता है। ग्रुपिंग सेट SQL सर्वर और ओरेकल दोनों में उपलब्ध हैं। MySQL के बारे में निश्चित नहीं है। –

उत्तर

2

सहायक तालिका को वास्तविक तालिका नहीं होना चाहिए, यह एक सामान्य तालिका अभिव्यक्ति हो सकती है - कम से कम यदि आप तालिका से सभी संभावित मान (या आप रुचि रखते हैं) प्राप्त कर सकते हैं। आप मूल्यों है कि तालिका में तो यह वैसे भी एक छोटे से अधिक जटिल (या भद्दा है नहीं हो सकता है तय कर दी है, तो

WITH CTE AS (
    SELECT * FROM (SELECT DISTINCT a FROM T) 
    JOIN (SELECT DISTINCT b, c FROM T) ON (1 = 1) 
) 
SELECT CTE.A, CTE.B, CTE.C, 
    SUM(CASE WHEN T.A IS NULL THEN 0 ELSE 1 END), NVL(SUM(T.D),0) 
FROM CTE 
LEFT JOIN T ON T.A = CTE.A AND T.B = CTE.B AND T.C = CTE.C 
GROUP BY CTE.A, CTE.B, CTE.C 
ORDER BY CTE.A, CTE.B, CTE.C; 

, और खराब हो जाता है: सभी संभव संयोजनों उत्पन्न करने के लिए @Bob जार्विस 'क्वेरी का उपयोग करके आप की तरह कुछ कर सकते हैं अधिक संभव मूल्यों के साथ):

WITH CTE AS (
    SELECT * FROM (SELECT DISTINCT a FROM T) 
    JOIN (SELECT 'B1' AS B FROM DUAL 
     UNION ALL SELECT 'B2' FROM DUAL) ON (1 = 1) 
    JOIN (SELECT 'C1' AS C FROM DUAL 
     UNION ALL SELECT 'C2' FROM DUAL) ON (1 = 1) 
) 
SELECT CTE.A, CTE.B, CTE.C, 
    SUM(CASE WHEN T.A IS NULL THEN 0 ELSE 1 END), NVL(SUM(T.D),0) 
FROM CTE 
LEFT JOIN T ON T.A = CTE.A AND T.B = CTE.B AND T.C = CTE.C 
GROUP BY CTE.A, CTE.B, CTE.C 
ORDER BY CTE.A, CTE.B, CTE.C; 

लेकिन आप कुछ कि 'लापता' मूल्यों के बारे में जानता है के लिए शामिल होना पड़ेगा। यदि एक ही तर्क की आवश्यकता कहीं और है, और आपने मूल्य निर्धारित किए हैं, तो एक स्थायी तालिका क्लीनर हो सकती है - रखरखाव की आवश्यकता हो सकती है। आप सरोगेट टेबल के रूप में कार्य करने के लिए एक पाइपलाइन फ़ंक्शन पर भी विचार कर सकते हैं, लेकिन वॉल्यूम पर निर्भर करता है।

+1

तालिका में सभी संभावनाएं हैं। जाहिर है, मैं उम्मीद नहीं कर रहा था कि डीबी इंजन उन्हें "अनुमान लगाएगा"। 'साथ' के दिलचस्प उपयोग के लिए +1, मैंने पहले कभी नहीं देखा है। –

1

बात यह है कि, यदि आपके डेटाबेस में कोई विशेष संयोजन नहीं है, तो इंजन को उस संयोजन को परिणामों में शामिल करने के बारे में कैसे पता चलेगा? परिणामों में सभी संयोजनों के लिए, आपको सभी संयोजन उपलब्ध होने की आवश्यकता है - चाहे मुख्य तालिका में या किसी अन्य तालिका में संदर्भ के लिए उपयोग किया जाए। उदाहरण के लिए, यदि आप ऐसा जैसे डेटा के साथ एक और तालिका आर बना सकते हैं:

A | B | C 
------------ 
A1 | B1 | C1 
A1 | B1 | C2 
A1 | B2 | C1 
A1 | B2 | C2 
A2 | B1 | C1 
A2 | B1 | C2 
A2 | B2 | C1 
A2 | B2 | C2 
A3 | B1 | C1 
A3 | B1 | C2 
A3 | B1 | C1 
A3 | B2 | C2 
... 

और फिर आपकी क्वेरी इस प्रकार दिखाई देगा:

SELECT r.*, COUNT(t.d), coalesce(SUM(t.d), 0) 
FROM r LEFT OUTER JOIN t on (r.a=t.a and r.b=t.b and r.c=t.c) 
GROUP BY r.a, r.b, r.c 
ORDER BY r.a, r.b, r.c 

इस रूप में आप संयोजन के लिए 0 | 0 साथ चाहते हैं आप सेट वापस आ जाएगी जो मुख्य तालिका में मौजूद नहीं है। ध्यान दें कि यह केवल तभी संभव है जब आप हर संभावित संयोजन को जानते हों जिसे आप शामिल करना चाहते हैं, जो हमेशा मामला नहीं हो सकता है।

दूसरी तरफ अपने ए, बी, सी संख्यात्मक मानों रहे हैं और आप केवल एक श्रेणी में सभी नंबरों को शामिल करना चाहते हैं, तो कुछ इस तरह इस से निपटने का एक और तरीका हो सकता है:

SELECT a.n, b.n, c.n, COUNT(t.d), coalesce(SUM(t.d), 0) 
FROM (SELECT (rownum) "n" FROM DUAL WHERE LEVEL >= start_a CONNECT BY LEVEL <= end_a) a, 
    (SELECT (rownum) "n" FROM DUAL WHERE LEVEL >= start_b CONNECT BY LEVEL <= end_b) b, 
    (SELECT (rownum) "n" FROM DUAL WHERE LEVEL >= start_c CONNECT BY LEVEL <= end_c) c, 
    t 
WHERE a.n = t.a(+) AND b.n = t.b(+) AND c.n = t.c(+) 
GROUP BY a.n, b.n, c.n 
ORDER BY a.n, b.n, c.n 

(मैं एक Oracle उदाहरण काम इस परीक्षण करने के लिए नहीं है, तो यह नहीं बल्कि कुछ और की तुलना में कुछ शिक्षित अनुमान की अधिक है।)

लब्बोलुआब यह इंजन है पता है कि फाइनल में शामिल करने के लिए की जरूरत है परिणाम - एक तरफ या दूसरा। सब एक के जो मौजूद साथ मिलकर

SELECT * FROM 
    (SELECT DISTINCT a FROM T) 
JOIN 
    (SELECT DISTINCT b, c FROM T) 
    ON (1 = 1) 
ORDER BY a, b, c 

यह आपको सभी संयोजनों जो बी और सी के अस्तित्व में दे देंगे,:

+0

इस तरह मैं इसे अभी कर रहा हूं। मेरे प्रश्न में अंतिम पैराग्राफ देखें। –

+0

@ lorenzo-s मुख्य समस्या यह है कि आप सभी वैध संयोजन निर्दिष्ट किए बिना, इंजन को जानने का कोई तरीका नहीं है, इसलिए आपको यह अस्थायी तालिका रखने की आवश्यकता है। –

+0

तालिका स्वयं (सभी पंक्तियों पर विचार करने) में (बी, सी) मानों के सभी संयोजन शामिल हैं। –

0

शायद खूबसूरत तरीके यह करने के लिए है, लेकिन निम्नलिखित आप की ओर शुरू कर दिया कि आप क्या चाहते मिलना चाहिए ,

A1 B1 C1 
A1 B1 C2 
A1 B2 C1 
A1 B2 C2 
A2 B1 C1 
A2 B1 C2 
A2 B2 C1 
A2 B2 C2 

साझा करें और आनंद लें।

+0

मैं कुछ खोज रहा हूं (और मैं इसे exixts नहीं मान रहा हूँ!) जिसमें शामिल नहीं है या तो ... मैं वर्तमान में एक तालिका का उपयोग कर रहा हूं जैसा आपने परिणाम प्राप्त करने के लिए लिखा था। मेरे प्रश्न में अंतिम पैराग्राफ देखें। –

+0

यहां मुद्दा अलग है। यदि तालिका टी में सभी संभावित संयोजन शामिल हैं, तो आप ठीक हैं, हालांकि यह नहीं है, तो आप वापस वर्ग में वापस आ गए हैं। किसी भी तरह डीबी इंजन को यह जानने की जरूरत है कि सभी संभावित संयोजन क्या हैं। –

+0

@AleksG ठीक है, ठीक है, हमारे पास यह समस्या नहीं है: तालिका स्वयं (सभी पंक्तियों पर विचार करने) में (बी, सी) मानों के सभी संयोजन शामिल हैं। जाहिर है, मैं उम्मीद नहीं कर रहा था कि डीबी इंजन उन्हें "अनुमान लगाएगा"। –

 संबंधित मुद्दे