2013-02-24 17 views
5

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

SELECT a.*, 
     COALESCE(b.totalCount, 0) AS CountWork, 
     COALESCE(b.totalAmount, 0) AS WorkTotal, 
     COALESCE(c.totalCount, 0) AS CountExpense, 
     COALESCE(c.totalAmount, 0) AS ExpenseTotal 
FROM clients A 
     LEFT JOIN 
     (
      SELECT Client, 
        COUNT(*) totalCount, 
        SUM(Amount) totalAmount 
      FROM work_times 
      WHERE DATE BETWEEN '2013-01-01' AND '2013-02-01' 
      GROUP BY Client 
     ) b ON a.Client = b.Client 
     LEFT JOIN 
     (
      SELECT Client, 
        COUNT(*) totalCount, 
        SUM(Amount) totalAmount 
      FROM expenses 
      WHERE DATE BETWEEN '2013-01-01' AND '2013-02-01' 
      GROUP BY Client 
     ) c ON a.Client = c.Client 
WHERE b.Client IS NOT NULL OR 
     c.Client IS NOT NULL 

आप एक पहेली here में काम कर रहे क्वेरी को देख सकते हैं।

मैं इस क्वेरी में संशोधन करने की कोशिश कर रहा हूं ताकि प्रत्येक ग्राहक के लिए प्रत्येक माह के लिए महीने और फिर ग्राहक द्वारा क्रमबद्ध प्रत्येक पंक्ति के लिए एक पंक्ति हो। मैं निम्नलिखित संशोधन क्वेरी के साथ ऐसा करने के लिए कोशिश कर रहा हूँ:

SELECT a.*, 
     COALESCE(b.totalCount, 0) AS CountWork, 
     COALESCE(b.totalAmount, 0) AS WorkTotal, 
     COALESCE(c.totalCount, 0) AS CountExpense, 
     COALESCE(c.totalAmount, 0) AS ExpenseTotal 
FROM clients A 
     LEFT JOIN 
     (
      SELECT Client, 
        COUNT(*) totalCount, 
        SUM(Amount) totalAmount, 
        SUBSTR(Date, 1, 7) as Month 
      FROM work_times 
      GROUP BY Month,Client 
      ORDER BY Month 
     ) b ON a.Client = b.Client 
     LEFT JOIN 
     (
      SELECT Client, 
        COUNT(*) totalCount, 
        SUM(Amount) totalAmount, 
        SUBSTR(Date, 1, 7) as Month 
      FROM expenses 
      GROUP BY Month,Client 
      ORDER BY Month,Client 
     ) c ON a.Client = c.Client 
WHERE b.Client IS NOT NULL OR 
     c.Client IS NOT NULL 

आप कार्रवाई here में संशोधन क्वेरी देख सकते हैं।

हालांकि यह काफी सही काम नहीं कर रहा है। क्लाइंट बी के लिए केवल एक पंक्ति लौटा दी गई है, भले ही जनवरी 2013 में कोई कार्य समय हो और फरवरी 2013 में एक व्यय (इसलिए 2 पंक्तियां होनी चाहिए) और ऐसा लगता है कि महीनों के विपरीत क्लाइंट द्वारा पंक्तियों का आदेश दिया जा रहा है। कोई सुझाव है सका वांछित आउटपुट प्राप्त करने के लिए क्वेरी में संशोधन करने के लिए कैसे दूसरी बेला पर उदाहरण के लिए जो होगा:

╔════════╦═══════════╦═══════════╦══════════════╦══════════════╗ 
║ CLIENT ║ COUNTWORK ║ WORKTOTAL ║ COUNTEXPENSE ║ EXPENSETOTAL ║ 
╠════════╬═══════════╬═══════════╬══════════════╬══════════════╣ 
║ A  ║   1 ║  10 ║   1 ║   10 ║ 
║ B  ║   1 ║  20 ║   0 ║   0 ║ 
║ A  ║   1 ║  15 ║   0 ║   0 ║ 
║ B  ║   0 ║  0 ║   1 ║   10 ║ 
║ C  ║   1 ║  10 ║   0 ║   0 ║ 
╚════════╩═══════════╩═══════════╩══════════════╩══════════════╝ 
+0

आप दो उप चयन के लिए 'आदेश BY' जरूरत नहीं है। बस इसे अंतिम उत्तर के लिए रखें। –

+1

यदि दिनांक एक डेटाटाइम डेटाटाइप है, तो आप इस पर एक substring() क्यों/कैसे करते हैं? – wildplasser

+0

आपकी तालिकाओं में अनावश्यक डेटा, राशि और तिथि है। आपको अपनी संरचना को और सामान्य बनाने और अनावश्यकता से छुटकारा पाने की आवश्यकता है। क्वेरी बहुत संदिग्ध है, आप विशिष्ट डेटा देखना चाहते हैं लेकिन ** क्लाइंट आईडी के अलावा किसी अन्य चयन में कोई मानदंड शून्य नहीं है **। यदि आप किसी निर्दिष्ट तिथि सीमा के लिए डेटा देखना चाहते हैं, तो महीने के अनुसार समूहित करें, फिर तिथि के लिए क्वेरी करें। मैं वापस कदम उठाऊंगा और अपनी पहली समस्या के रूप में सामान्यीकरण को देखूंगा। –

उत्तर

2

जब तक मुझे आवश्यकताओं में कुछ याद नहीं आ रहा है, आपको क्या करना है, ग्राहकों और तिथियों की एक सूची प्राप्त करें और फिर अपनी उप-श्रेणियों में शामिल हों। तो आपकी क्वेरी होगी:

SELECT a.*, 
    COALESCE(b.totalCount, 0) AS CountWork, 
    COALESCE(b.totalAmount, 0) AS WorkTotal, 
    COALESCE(c.totalCount, 0) AS CountExpense, 
    COALESCE(c.totalAmount, 0) AS ExpenseTotal 
FROM 
(
    select distinct c.Client, d.Month 
    from clients c 
    cross join 
    (
    select SUBSTR(Date, 1, 7) as Month 
    from work_times 
    union 
    select SUBSTR(Date, 1, 7) as Month 
    from expenses 
) d 
) A 
LEFT JOIN 
(
    SELECT Client, 
    COUNT(*) totalCount, 
    SUM(Amount) totalAmount, 
    SUBSTR(Date, 1, 7) as Month 
    FROM work_times 
    GROUP BY Month,Client 
    ORDER BY Month,Client 
) b 
    ON a.Client = b.Client 
    and a.month = b.month 
LEFT JOIN 
(
    SELECT Client, 
    COUNT(*) totalCount, 
    SUM(Amount) totalAmount, 
    SUBSTR(Date, 1, 7) as Month 
    FROM expenses 
    GROUP BY Month,Client 
    ORDER BY Month,Client 
) c 
    ON a.Client = c.Client 
    and a.month = c.month 
WHERE b.Client IS NOT NULL OR 
     c.Client IS NOT NULL 
order by a.month, a.client 

SQL Fiddle with Demo देखें।

परिणाम है:

| CLIENT | MONTH | COUNTWORK | WORKTOTAL | COUNTEXPENSE | EXPENSETOTAL | 
-------------------------------------------------------------------------- 
|  A | 2013-01 |   1 |  10 |   1 |   10 | 
|  B | 2013-01 |   1 |  20 |   0 |   0 | 
|  A | 2013-02 |   1 |  15 |   0 |   0 | 
|  B | 2013-02 |   0 |   0 |   1 |   20 | 
|  C | 2013-02 |   1 |  10 |   0 |   0 | 
+0

नहीं, आप कुछ भी याद नहीं कर रहे हैं।आपकी क्वेरी ठीक वही देता है जो मैं चाहता हूं। आपका बहुत बहुत धन्यवाद! – Nick

+0

@ मदद करने के लिए निक खुश, मैंने मूल क्वेरी में थोड़ा सा संपादन किया है लेकिन यह अभी भी एक ही परिणाम देता है। :) – Taryn

+0

आपके संपादन का परिणाम काफी समान नहीं लगता है। इसे – Nick

0

आप एक उप क्वेरी में से एक आदेश करते हैं, यह कोई बात नहीं है, क्योंकि बाहरी क्वेरी परिणामों को फिर से ऑर्डर कर सकती है (और इसकी आवश्यकता हो सकती है)। आप बाहरी क्वेरी द्वारा ऑर्डर जोड़ना चाहते हैं।

आपकी समस्या यह है कि आप बी तालिका के महीने और ग्राहक द्वारा क्रमबद्ध करने की कोशिश कर रहे हैं, और सी तालिका के महीने और ग्राहक द्वारा ऑर्डर भी कर रहे हैं। आपको बीमोन, बीक्लिएंट और सीएमथ के क्रम को परिभाषित करने की आवश्यकता है और बाहरी क्वेरी के लिए इसे एक ऑर्डर में डालना होगा।

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

+0

धन्यवाद, कार्य-समय और व्यय पंक्तियों दोनों को बेवकूफ में 'माह, ग्राहक' द्वारा समूहीकृत किया जाता है। मैंने इसे प्रतिबिंबित करने के लिए अपने प्रश्न में क्वेरी में संशोधन किया है। यह सुनिश्चित नहीं है कि मैं परिणाम प्राप्त कर सकता हूं जिसे मैं बाहरी क्वेरी द्वारा केवल एक ऑर्डर जोड़कर ढूंढ रहा हूं। मैंने कुछ संयोजनों की कोशिश की है और यह काम नहीं कर रहा है। समस्या का एक हिस्सा यह है कि क्लाइंट बी के लिए व्यय और कार्य समय एक ही पंक्ति में संयुक्त हो रहा है, भले ही वे एक अलग महीने में हों। – Nick

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