2010-03-23 17 views
18

के साथ जुड़ें मेरे पास दो टेबल हैं। indRailType में आईडी प्रकार के साथ जोड़े गए नामों की एक सूची है जो मैं रेल प्रकार को इंगित करने के लिए अन्य तालिकाओं में उपयोग करता हूं। WO_BreakerRail में एक दिनांक कॉलम और एक रेल कोड कॉलम है जो indRailType और कुछ अन्य डेटा में एक ही कोड से मेल खाता है। प्रत्येक तारीख के लिए प्रत्येक रेल प्रकार पर किसी भी गतिविधि के लिए WO_BreakerRail में एक पंक्ति है। तो मेरे पास 3/19/2010 के लिए 3 पंक्तियां हो सकती हैं, प्रत्येक पंक्ति एक अलग रेल कोड इंगित करती है, और क्या हुआ।बाएं आउटर एक WHERE क्लॉज

जब मैं निम्नलिखित LEFT OUTER JOIN का उपयोग करता हूं, तो मुझे पंक्तियों में नल के साथ सभी प्रकार के रेल के साथ एक टेबल मिलता है, जहां 1 9वीं पर कुछ भी नहीं हुआ था। अब, यह केवल काम कर रहा है क्योंकि मेरे पास केवल WO_BreakerRail तालिका में 1 9वीं की एक तिथि है। जब मैं अलग-अलग तिथियों के साथ और पंक्तियां जोड़ता हूं, तो चीजें खराब हो जाएंगी।

यह मेरा एसक्यूएल बयान है, जो अभी मुझे बिल्कुल गये परिणाम देता है:

SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
FROM indRailType 
LEFT OUTER JOIN WO_BreakerRail 
    ON indRailType.RailCode = WO_BreakerRail.RailCode 

अब, जब मैं एक WHERE WO_BreakerRail.Date = @Date खंड मैं JOIN जो कुछ भी नहीं हुआ की सभी पंक्तियों खो में जोड़ें। मुझे वह नहीं चाहिए। पढ़ने से, यह एक पूर्ण OUTER JOIN जैसा लगता है जो मैं चाहता हूं, लेकिन SQL सर्वर कॉम्पैक्ट संस्करण FULL OUTER JOIN एस का समर्थन नहीं करता है। क्या इसके आसपास कोई रास्ता है, या क्या मैं पूरी तरह से कुछ और ढूंढ रहा हूं?

उत्तर

35

आज़माएं:

SELECT WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
FROM indRailType 
LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode 
      AND WO_BreakerRail.Date = @Date 

इस प्रकार में शामिल होने

+1

@Date के "समय" हिस्से में कारक को न भूलें। यदि मध्यरात्रि और आधी रात के बीच मूल्य भिन्न हो सकते हैं, तो आपको क्लॉज के बीच कुछ रूपों का उपयोग करना होगा। –

+0

यह उत्तर पूरी तरह से काम किया, धन्यवाद। फिलिप: उस सूचक के लिए धन्यवाद, हालांकि मैं इस परियोजना में पहले इस समस्या में भाग गया था, जो मुझे थोड़ी देर के लिए फेंक दिया, लेकिन मैंने इसे अपने सी # कोड में फिक्स कर दिया, सभी समय के हिस्सों को हटा दिया, हर रात आधी रात को डिफॉल्ट कर दिया। – Wesley

+1

@ वेस्ले, समय निकालने के लिए "फर्श" डेटाटाइम डेटा प्रकारों के लिए सबसे अच्छा है, इसलिए समय 00: 00: 00.000 है और मध्यरात्रि नहीं है। –

2

जोड़ने LEFT OUTER JOIN बयान पर WO_BreakerRail.Date = @Date और नहीं WHERE:

SELECT 
    WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
    FROM indRailType 
     LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode AND WO_BreakerRail.Date = @Date 

या आप कहां में जोड़ सकते हैं:

SELECT 
    WO_BreakerRail.ID, indRailType.RailType, WO_BreakerRail.CreatedPieces, WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
    FROM indRailType 
     LEFT OUTER JOIN WO_BreakerRail ON indRailType.RailCode = WO_BreakerRail.RailCode 
    WHERE (WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL) 
5

आप इस इस्तेमाल कर सकते हैं जहां खंड:

WHERE WO_BreakerRail.Date = @Date OR WO_BreakerRail.Date IS NULL 
+3

जब बाहरी के साथ काम करने में मिलती है, यह करने के लिए सबसे अच्छा है च ऑन क्लॉज में अभिनेता किसी भी "अनावश्यक काम", और जहां धारा –

15

विधेय हालत में शामिल होने के लिए On खंड में होने की जरूरत है पर AND WO_BreakerRail.Date = @Date जोड़ने, जहां खंड में नहीं। जिस तरह से बाहरी काम में शामिल होता है, जुड़ने की स्थितियों का विश्लेषण करने के बाद, "बाहरी तरफ" की सभी पंक्तियां जो आंतरिक तरफ से मेल नहीं खाती हैं .... लेकिन यह सब क्लॉज संसाधित होने से पहले होता है। तो यदि जहां खंड बाहरी बहिष्कार के बाहरी पक्ष से एक विशेषता पर फिल्टर अनुमानित करता है, तो उन सभी पंक्तियों को फिर से हटा दिया जाएगा ... (वे सभी शून्य हैं)। में शामिल होने हालत बजाय में विधेय रखो, तो यह पहले लापता पंक्तियों पीठ में जोड़ रहे हैं का मूल्यांकन किया जाएगा ...

SELECT b.ID, t.RailType, b.CreatedPieces, 
     b.OutsideSource, b.Charged, b.Rejected, 
     b.RejectedToCrop 
FROM indRailType t 
    LEFT JOIN WO_BreakerRail b 
     ON t.RailCode = b.RailCode 
      And b.Date = @Date 
0

क्या आप चाहते हैं इससे पहले कि वाम को इसमें शामिल होने के लिए अपने WO_BreakerRail इच्छित तिथि को फिल्टर करने के लिए है indRailType पर। यदि आप केवल WHERE कथन जोड़ते हैं, तो यह दूसरी तरफ किया जाता है, जिसके परिणामस्वरूप आपने वर्णित समस्या का परिणाम दिया है।

अब तक प्रदान काम करना चाहिए समाधान (बाएं में हालत के लिए कदम शामिल हों), लेकिन मैं एक वैकल्पिक सुझाव देना चाहते हैं:

: आप जिस क्रम में बातें किया जाना चाहिए निर्दिष्ट करने के लिए उपयोग कर सकते हैं सबक्वेरी
SELECT R.ID, indRailType.RailType, R.CreatedPieces, R.OutsideSource, R.Charged, R.Rejected, R.RejectedToCrop 
    FROM indRailType LEFT OUTER JOIN 
     (SELECT * FROM WO_BreakerRail WHERE Date = @Date) R 
     ON indRailType.RailCode = R.RailCode 

(untested है, लेकिन जहां तक ​​मुझे पता है, एसक्यूएल सर्वर सीई सबक्वेरी समर्थन करता है।)

1

या आप WHERE में जोड़ सकते हैं:

SELECT WO_BreakerRail.ID, indRailType.RailType, 
    WO_BreakerRail.CreatedPieces, 
    WO_BreakerRail.OutsideSource, WO_BreakerRail.Charged, 
    WO_BreakerRail.Rejected, WO_BreakerRail.RejectedToCrop 
FROM indRailType, WO_BreakerRailCode 
WHERE indRailType.RailCode = WO_BreakerRail.RailCode(+) 
AND WO_BreakerRail.Date (+) [email protected] 
+0

'(+)' ओरेकल ऑपरेटर में शामिल हों और ओपी एसक्यूएल-सर्वर का उपयोग कर रहा है। साथ ही, बाह्य जुड़ने के लिए उस वाक्यविन्यास को उपयोग के लिए अनुशंसित नहीं किया जाता है क्योंकि यह अधिक सीमित है और मानक 'बाएं जॉइन' वाक्यविन्यास पढ़ने के लिए और अधिक कठिन है। [ओरेकल डॉक्स: जुड़ता है] (https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm) – Wayne