मेरे पास निम्न क्वेरी है जो 4 परिणाम लौटा रही है जब तालिका FI_CurrentReceiptData में केवल 2 पंक्तियां होती हैं। अतिरिक्त पंक्तियाँ सटीक डुप्लिकेट हैं। मैं ठीक करने के लिए DISTINCT
का उपयोग कर सकता हूं, लेकिन मेरी समझ यह है कि यह खराब अभ्यास है और मैं त्रुटि को खोजने और ठीक करने के लिए बेहतर करूंगा (क्या यह सही है?)
यह प्रश्न परिणामों को दोगुना क्यों कर रहा है?
सभी चर एक संग्रहीत प्रक्रिया में कहीं और घोषित किए जाते हैं और यह क्वेरी आवश्यक फ़ील्ड लौटाती है।
SELECT ( (Select Max(ReceiptNumber)
from Avanti_InventoryReceipts) + CR.Seq ),
CR.ItemNumber,
Convert(char(8), GETDATE(), 112),
PONum,
'FL-INV',
PH.POVendor,
0,
0,
'O',
CR.QtyOrdered,
QtyReceivedToday,
QtyReceivedToday,
Case @closePO
When 'N' Then Case
When ( QtyOrdered - QtyReceivedToday ) < 0 Then 0
Else ( QtyOrdered - QtyReceivedToday )
End
When 'Y' Then 0
Else 0
End,
PD.TransCost * QtyReceivedToday,
IH.PriceWholeSale,
IH.CostLast,
QtyReceivedToday,
0,
'',
PODetailDescription /* , .... More columns...*/
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD
ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH
ON CR.PONum = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH
ON CR.ItemNumber = IH.ItemNumber
नया जहां क्लॉज समाधान:
FROM FI_CurrentReceiptData CR
inner JOIN Avanti_PODetails PD ON CR.PONum = PD.PONumber AND CR.ItemNumber = PD.TransItem AND CR.QtyOrdered = PD.TransQty
left JOIN Avanti_POHeader PH ON PD.PONumber = PH.PONumber
left JOIN Avanti_InventoryHeader IH ON CR.ItemNumber = IH.ItemNumber
3 जवाब
सम्मिलित तालिकाओं में से एक में एक से अधिक मेल खाने वाली पंक्तियाँ हैं। मैं निश्चित रूप से नहीं कह सकता कि कौन सा है, लेकिन अगर मैं तुम होते तो मैं Avanti_PODetails तालिका को देखना शुरू कर देता। क्या इसके पास दो रसीदों में से किसी एक के लिए एक से अधिक मिलान रिकॉर्ड हैं?
DISTINCT
से बचने की कोशिश करने का अधिकार है, हां?
आमतौर पर जब आप लेफ्ट जॉइन करते हैं, तो आपको 'लेफ्ट' टेबल से जुड़ते रहना होता है - यह एक नियम नहीं है बल्कि यह अच्छा अभ्यास है ताकि आप जुड़ने से न चूकें। आपके लेफ्ट जॉइन की स्ट्रिंग में, इसमें 4 टेबल शामिल हैं, और आप तीनों में से केवल पहले वाले में शामिल हुए हैं:
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD
ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH
ON CR.PONum = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH
ON CR.ItemNumber = IH.ItemNumber
आप पीडी से आईएच से पीएच में शामिल नहीं हो रहे हैं, लेकिन मूल रूप से सीआर तालिका में तीनों में शामिल होना छोड़ दिया है - इसलिए अनिवार्य रूप से यह पीडी और पीएच और आईएच के बीच एक क्रॉस जॉइन कर रहा है (जो भी फ़ील्ड वे मेल खाते हैं उसके आधार पर)। मुझे लगता है कि POheader और POdetails में कुछ फ़ील्ड हैं जिन पर वे मेल खाते हैं .... और मुझे लगता है कि यह तालिकाओं के बीच कई संबंधों में से एक है? (नामों के आधार पर)। तो वहां कुछ प्रतिबंध लगाने की जरूरत है ...
संपादित करें:
तो क्या आप कोशिश कर सकते हैं, (क्षेत्र संबंधों के आधार पर)
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD
ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH
ON CR.PONum = PH.PONumber AND PD.PONumber = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH
ON CR.ItemNumber = IH.ItemNumber
संपादित करें 2:
ठीक है, तो आप जो कह रहे हैं, उसके अनुसार CR में 2 पंक्तियाँ हैं, और CR का PH से 1-से-1 संबंध है, और PH का PD से 1-से-अनेक संबंध है। और CR का IH से 1-टू-टी संबंध भी है। इस मामले में, यह मानते हुए कि आपके पास रेफरेंसियल अखंडता है, आप अपने जॉइन को इसमें बदल सकते हैं:
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_POHeader PH ON CR.PONum = PD.PONumber
INNER JOIN Avanti_PODetails PD ON PH.PONumber = PD.PONUmber
LEFT JOIN Avanti_InventoryHeader IH ON CR.ItemNumber = IH.ItemNumber
आइए एक कदम पीछे हटें - यह पीडी और पीएच पंक्तियों को इस आधार पर प्रतिबंधित करेगा कि वे मेल खाते हैं या नहीं, और यदि वे नहीं करते हैं तो भी शून्य नहीं मिलेगा (जो कि बाएं जुड़ता है)।
लेकिन अब, यदि आपके पास CR में 2 पंक्तियाँ हैं, और प्रत्येक PONumbers में POHeader में 2 पंक्तियाँ हैं, और प्रत्येक POHeader में POdetails में 1 से अधिक पंक्तियाँ हैं, तो आपके पास निश्चित रूप से डुप्लिकेट होंगे। इससे बचने का वास्तव में कोई उपाय नहीं है। कारण यह है:
सीआर टेबल
PONum ItemNumber
--------- ----------
123 ABC
456 DEF
पीएच तालिका
PONumber
---------
123
456
पीडी टेबल
PONumber ItemNumber
--------- -----------
123 ABC
123 ABC1
456 DEF
456 DEF1
...यदि आप CR तालिका को PH तालिका में शामिल करते हैं, तो आपको केवल दो पंक्तियाँ मिलेंगी। यदि आप PH से PD टेबल में शामिल हो जाते हैं, तो आपको 4 पंक्तियाँ मिलेंगी। यदि आप सभी 3 को जोड़ते हैं, तो आपको 4 पंक्तियाँ भी मिलेंगी। शामिल होने की प्रकृति सभी तालिका में है, इसलिए जब आप सीआर तालिका से पीएच पर जाते हैं, तो उसे 2 पंक्तियों का परिणाम मिलता है ... और फिर वह परिणाम पीडी में शामिल हो जाता है, और वहां 4 पंक्तियां होती हैं। यदि आप पुष्टि कर सकते हैं कि आपका डेटा ऐसा है, तो आपको जो परिणाम मिल रहा है वह सही है।
चूंकि आप लेफ्ट जॉइन कर रहे हैं, आपको सभी मिलान रिकॉर्ड के लिए 1 पंक्ति वापस मिल जाएगी। तो आप जिन तालिकाओं में शामिल हो रहे हैं उनमें से एक 1 से अधिक पंक्ति लौटा रहा है।
कॉलम सूची में अन्य टेबल प्राथमिक कुंजी जोड़ने के लिए अपनी क्वेरी को अस्थायी रूप से बदलने का प्रयास करें और आपको जल्दी से यह बताने में सक्षम होना चाहिए कि कौन सी तालिका 1 से अधिक पंक्ति लौटा रही है।
संबंधित सवाल
नए सवाल
sql
संरचित क्वेरी भाषा (एसक्यूएल) डेटाबेस को क्वेरी करने के लिए एक भाषा है। प्रश्नों में कोड उदाहरण, तालिका संरचना, नमूना डेटा और DBMS कार्यान्वयन के लिए एक टैग (जैसे MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2, आदि) का उपयोग किया जाना चाहिए। यदि आपका प्रश्न केवल एक विशिष्ट DBMS (विशिष्ट एक्सटेंशन / सुविधाओं का उपयोग करता है) से संबंधित है, तो इसके बजाय उस DBMS के टैग का उपयोग करें। एसक्यूएल के साथ टैग किए गए सवालों के जवाब में आईएसओ / आईईसी मानक एसक्यूएल का उपयोग करना चाहिए।