2009-08-06 10 views
6

मुझे निम्नलिखित डीबी डिज़ाइन विरासत में मिला है। टेबल्स हैं:एसक्यूएल जॉइन, कुल मिलाकर प्राप्त करने के लिए तीन टेबल पर समूह

customers 
--------- 
customerid 
customernumber 

invoices 
-------- 
invoiceid 
amount 

invoicepayments 
--------------- 
invoicepaymentid 
invoiceid 
paymentid 

payments 
-------- 
paymentid 
customerid 
amount 

मेरे क्वेरी invoiceid वापस जाने के लिए की जरूरत है, चालान राशि (चालान तालिका में), और देय राशि (चालान राशि शून्य से किसी भी भुगतान कि चालान की ओर किए गए हैं) किसी दिए गए CUSTOMERNUMBER के लिए। एक ग्राहक के पास कई चालान हो सकते हैं।

निम्न क्वेरी मुझे रिकॉर्ड नकल देता है जब कई भुगतान एक चालान करने के लिए बना रहे हैं:

SELECT i.invoiceid, i.amount, i.amount - p.amount AS amountdue 
FROM invoices i 
LEFT JOIN invoicepayments ip ON i.invoiceid = ip.invoiceid 
LEFT JOIN payments p ON ip.paymentid = p.paymentid 
LEFT JOIN customers c ON p.customerid = c.customerid 
WHERE c.customernumber = '100' 

मैं यह कैसे हल कर सकते हैं?

+0

एक चालान के लिए कितनी चालान भुगतान पंक्तियां मौजूद हो सकती हैं? प्रत्येक भुगतानकर्ता के लिए कितने भुगतान मौजूद हो सकते हैं? –

उत्तर

10

मुझे यकीन है कि मैं तुम्हें मिल गया है, लेकिन इस हो सकता है आप के लिए क्या देख रहे नहीं कर रहा हूँ:

SELECT i.invoiceid, sum(case when i.amount is not null then i.amount else 0 end), sum(case when i.amount is not null then i.amount else 0 end) - sum(case when p.amount is not null then p.amount else 0 end) AS amountdue 
FROM invoices i 
LEFT JOIN invoicepayments ip ON i.invoiceid = ip.invoiceid 
LEFT JOIN payments p ON ip.paymentid = p.paymentid 
LEFT JOIN customers c ON p.customerid = c.customerid 
WHERE c.customernumber = '100' 
GROUP BY i.invoiceid 

यह आपको मात्रा में रकम के मामले में प्रत्येक चालान के लिए कई भुगतान पंक्तियां हैं मिलेगा

+1

आपको शायद 'राशि' कॉलम को 'coalesce' या' isnull' में लपेटना चाहिए; एमएस-एसक्यूएल के साथ, कोई भी शून्य मान, उदा। 'बाएं जॉइन' से पूरी चीज को पूर्ण करने का कारण बन जाएगा। मुझे पता है कि कुछ एसक्यूएल बोलियां NULL == 0 की अनुमति देती हैं, लेकिन इससे धार्मिक युद्ध होता है, इसलिए ... – Adrien

+0

आप सही हैं, मैंने "केस" क्लॉज जोड़े क्योंकि मुझे यकीन नहीं है कि एसक्यूएल डीबीएमएस hes क्या उपयोग कर रहा है। धन्यवाद! –

+0

व्यक्तिगत रूप से, मैं चालान राशि को एसयूएम नहीं करूँगा - यह मानते हुए कि चालान एक प्राथमिक कुंजी है और चालान तालिका में राशि को शून्य नहीं माना जाता है - और इसके बजाय ग्रुप बाय क्लॉज में i.amount जोड़ें। –

2

पहले सभी में, चालान तालिका में ग्राहक आईडी नहीं होना चाहिए? वैसे भी, आप चालान के लिए यह क्वेरी नहीं कर सकते हैं जिनके पास अभी तक कोई भुगतान नहीं है। यदि चालान पर कोई भुगतान नहीं है, तो वह चालान क्वेरी के आउटपुट में भी दिखाई नहीं देगा, भले ही यह बाहरी शामिल हो ...

इसके अलावा, जब कोई ग्राहक भुगतान करता है, तो आप कैसे जानते हैं चालान इसे संलग्न करने के लिए? यदि भुगतान के साथ आने वाले स्टब पर इनवॉइस आईडी द्वारा एकमात्र तरीका है, तो आप उन ग्राहकों के साथ इनवॉइस को जोड़ते हुए (शायद अनुपयुक्त) हैं जो ग्राहक ने उन्हें आदेश दिया है ...। (कभी-कभी किसी चालान को ग्राहक के अलावा किसी अन्य व्यक्ति द्वारा भुगतान किया जा सकता है)

+0

ये वास्तव में अच्छे अंक हैं; हालांकि मैं कहूंगा कि आपका अंतिम बयान एक व्यापार नियम है जो पोस्टर की कंपनी में सच हो सकता है या नहीं भी हो सकता है। कुल मिलाकर, डिज़ाइन गन्दा है, और जैसा कि बाहरी जुड़ने का उपयोग करने में कोई बात नहीं है, क्योंकि भविष्यवाणी की आवश्यकता है कि ग्राहकों को –

4

उत्तर के लिए बहुत बहुत धन्यवाद!

सगी मालचाई, दुर्भाग्य से वह प्रश्न उन मामलों में चालान राशि बताता है जहां एक से अधिक भुगतान हैं। कहें कि $ 18 और $ 12 के $ 39 चालान में दो भुगतान हैं।

1 39.00 9.00 

आप के साथ खत्म हो जाएगा:: तो बजाय कि लग रहा है एक परिणाम की तरह साथ समाप्त की तुलना में

1 78.00 48.00 

चार्ल्स Bretana, मेरी क्वेरी सरल संभव क्वेरी मैं करने के लिए छंटाई के दौरान (बेवकूफ) एक अतिरिक्त टेबल, ग्राहक सेवा, जो ग्राहकों और चालानों के बीच एक लिंक प्रदान करता है छोड़ दिया। इसका उपयोग चालान देखने के लिए किया जा सकता है जिसके लिए भुगतान नहीं किए गए हैं।

बहुत संघर्ष करने के बाद, मुझे लगता है कि निम्न क्वेरी देता है क्या मैं इसे करने की जरूरत है:

SELECT DISTINCT i.invoiceid, i.amount, ISNULL(i.amount - p.amount, i.amount) AS amountdue 
FROM invoices i 
LEFT JOIN invoicepayments ip ON i.invoiceid = ip.invoiceid 
LEFT JOIN customerinvoices ci ON i.invoiceid = ci.invoiceid 
LEFT JOIN (
    SELECT invoiceid, SUM(p.amount) amount 
    FROM invoicepayments ip 
    LEFT JOIN payments p ON ip.paymentid = p.paymentid 
    GROUP BY ip.invoiceid 
) p 
ON p.invoiceid = ip.invoiceid 
LEFT JOIN payments p2 ON ip.paymentid = p2.paymentid 
LEFT JOIN customers c ON ci.customerid = c.customerid 
WHERE c.customernumber='100' 

तुम लोग सहमत हैं?

+0

हाँ से एक पंक्ति वापस कर दी जाए, यह अच्छा लग रहा है। – RiddlerDev

2

मेरे पास उन लोगों के लिए एक टिप है, जो एक ही तालिका से विभिन्न समेकित मूल्य प्राप्त करना चाहते हैं।

आइए कहें कि मेरे पास उपयोगकर्ता और तालिका के साथ टेबल है जो उपयोगकर्ता प्राप्त करते हैं। तो उनके बीच कनेक्शन 1: एन (एक उपयोगकर्ता, कई अंक रिकॉर्ड) है।

अब तालिका 'अंक' में मैं जानकारी के बारे में जानकारी संग्रहीत करता हूं कि उपयोगकर्ता को अंक प्राप्त करने के लिए क्या किया गया था (लॉगिन, बैनर आदि पर क्लिक करना)।और मैं SUM(points) और फिर SUM(points WHERE type = x) द्वारा आदेशित सभी उपयोगकर्ताओं को सूचीबद्ध करना चाहता हूं। यह कहने के लिए उपयोगकर्ता के सभी बिंदुओं द्वारा आदेश दिया गया है और उसके बाद उपयोगकर्ता को एक विशिष्ट कार्रवाई (उदाहरण के लिए लॉगिन) के लिए मिला है।

एसक्यूएल होगा:

SELECT SUM(points.points) AS points_all, SUM(points.points * (points.type = 7)) AS points_login 
FROM user 
LEFT JOIN points ON user.id = points.user_id 
GROUP BY user.id 

इस की सुंदरता SUM(points.points * (points.type = 7)) जहां भीतरी कोष्ठक या तो 0 या 1 का मूल्यांकन इस प्रकार 0 या 1 द्वारा दिए गए अंक मूल्य गुणा, निर्भर करता है wheteher यह बराबर होती है पर में है हम चाहते हैं कि अंक के प्रकार के लिए।