क्या मैं बाएं बाहरी जुड़ने के लिए डिफ़ॉल्ट प्रदान कर सकता हूं?


21

मान लीजिए कि मेरे पास एक टेबल है (कॉलम a1 के साथ) और b (कॉलम b1 और b2 के साथ) और मैं बाईं ओर बाहरी प्रदर्शन करता हूं

SELECT *
FROM a LEFT OUTER JOIN b
ON a.a1 = b.b1

फिर b1 और b2 NULL होगा जहाँ a1 के मान का b1 का कोई मिलान मूल्य नहीं है।

क्या मैं NULL के बजाय b2 के लिए डिफ़ॉल्ट मान प्रदान कर सकता हूं? ध्यान दें कि COALESCE यहाँ काम नहीं करेगा, क्योंकि मैं नहीं है डिफ़ॉल्ट मान b2 में संभावित NULLs ओवरराइड करने के लिए जहां चाहते है B1 मिलान a1 के एक मूल्य।

यह है, एक और बी के साथ के रूप में

CREATE TABLE a (a1)
  AS VALUES (1),
            (2),
            (3) ;

CREATE TABLE b (b1,b2)
  AS VALUES (1, 10),
            (3, null) ;


a1     b1 | b2
---    --------
 1      1 | 10
 2      3 | NULL
 3

और बी 2 के लिए एक डिफ़ॉल्ट, कहते हैं, 100, मैं परिणाम प्राप्त करना चाहता हूं

a1 | b1   | b2
---------------
1  |  1   | 10
2  | NULL | 100
3  |  3   | NULL

इस सरल मामले में मैं इसे "हाथ से" कर सकता था, यह देखकर कि आउटपुट में b1 NULL है या नहीं। क्या यह सामान्य रूप से सबसे अच्छा विकल्प है, या एक अधिक मानक और खाने का तरीका है?

जवाबों:


23
SELECT a.a1,b.b1,  
    CASE WHEN b.b1 is NULL THEN 5 ELSE b.b2 END AS b2  
FROM a LEFT OUTER JOIN b  
ON a.a1 = b.b1

2
कृपया ANSI SQL का उपयोग करें जब प्रश्न केवल टैग किया गया हो sql(जिसका अर्थ है "SQL क्वेरी भाषा"। यह टैग किसी विशिष्ट DBMS उत्पाद या बोली को निरूपित नहीं करता है)। हिस्सा: [b2]=CASE WHEN ... ENDएक अमान्य (मानक) SQL अभिव्यक्ति है।
a_horse_with_no_name

मैंने यह दर्शाने के लिए एक टैग जोड़ा है कि मैं पोस्टग्रेज के विशिष्ट उत्तर को स्वीकार करूंगा। फिर भी, यदि संभव हो तो मानक एसक्यूएल को प्राथमिकता दी जाएगी।
टॉम एलिस

@ किन: जैसा कि मेरे प्रश्न में कहा गया है कि मुझे पता है कि "मैं इसे हाथ से कर सकता हूं" यह देखकर कि क्या आउटपुट में b1 NULL है? क्या यह सामान्य रूप से सबसे अच्छा विकल्प है, या एक अधिक मानक और एनटर तरीका है? "
टॉम एलिस

3
चूँकि आप एक JOIN के कारण होने वाले NULL के बीच अंतर करना चाहते हैं और जो "स्वाभाविक रूप से" मौजूद हैं, यह अपरिहार्य है कि आपको b1 की जांच करनी होगी। यदि आपके लिए इसका मतलब है कि "मैं इसे हाथ से" कर सकता हूं ", तो हां, यह एकमात्र तरीका है।
मोर्दकै

@MorDeror: ठीक है, मुझे लगता है कि मैं सोच रहा था कि एक वाक्यविन्यास हो सकता है जैसे कि "LEFT OUTER JOIN ... ON ... DEFAULT b2 = ..."।
टॉम एलिस

2

इस प्रश्न का मूल उत्तर अस्पष्टीकृत है, तो चलिए इसे दूसरा शॉट देते हैं।

CASEकथन का उपयोग करना

इस पद्धति का उपयोग करके हम शोषण करते हैं कि हमारे पास एक अलग कॉलम में एक और मूल्य है किIS NOT NULL इस मामले में b.b1यदि वह मान शून्य है, तो हमें पता है कि इसमें विफल रहा है।

SELECT
  a.a1,
  b.b1,  
  CASE WHEN b.b1 is NULL THEN 100 ELSE b.b2 END AS b2  
FROM a
LEFT OUTER JOIN b  
  ON (a.a1 = b.b1);

यह पूरी तरह से काम करेगा, और आपके द्वारा वांछित सटीक चीज़ उत्पन्न करेगा।

उप-चयन का उपयोग करना

इस पद्धति का उपयोग न करें, यह बिल्ड-अप विचार है। पढ़ते रहिये।

यदि हमारे पास ऐसा कोई NOT NULLकॉलम नहीं है जिसका हम उस तरह से शोषण कर सकें, तो हमें एक ऐसा कॉलम बनाने की जरूरत है, जो हमारे लिए इस तरह से कार्य कर सके ...

SELECT
  a.a1,
  b.b1,  
  CASE WHEN b.cond IS NULL THEN 100 ELSE b.b2 END AS b2  
FROM a
LEFT OUTER JOIN (
  SELECT true AS cond, b.*
  FROM b
) AS b
  ON (a.a1 = b.b1);

एक पंक्ति तुलना का उपयोग करना

फिर भी आसान है, फिर एक गलत मूल्य जिसके लिए हम तुलना कर सकते हैं, पंक्ति की तुलना करना है। PostgreSQL में, तालिका के नाम से पंक्ति का मान होता है। उदाहरण के लिए, तालिका से प्रकार की एक पंक्ति (जो एक पंक्ति प्रकार है) SELECT foo FROM fooलौटाता है । यहां हम यह देखने के लिए परीक्षण करते हैं कि क्या ROW शून्य है। यह हर कॉलम की तरह लंबे समय तक काम करेगा । और, यदि आपकी तालिका में प्रत्येक स्तंभ , तो आप केवल ट्रोल कर रहे हैं।foofooIS NOT NULLIS NULL

SELECT
  a.a1,
  b.b1,  
  CASE WHEN b IS NULL THEN 100 ELSE b.b2 END AS b2  
FROM a
LEFT OUTER JOIN b
  ON (a.a1 = b.b1);

समाधान b1में प्रयुक्त स्तंभ CASEको गैर-अशक्त होने की आवश्यकता नहीं है। निर्माण या तो मामलों में काम करता है।
ypercube y

1

मुझे लगता है कि मामला उस मामले में बहुत उपयोगी है। यह सूची से पहला गैर NULL मान लौटाएगा:

SELECT
 a.a1,
 b.b1,
 COALESCE (b.b2, 100) AS b2
FROM a
LEFT OUTER JOIN b
  ON (a.a1 = b.b1);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.