एक सेट में दो कॉलम का चयन करना


35

यह एक मूर्खतापूर्ण प्रश्न हो सकता है, और मेरा संदेह यह है कि मैं ऐसा नहीं कर सकता, लेकिन SQL में एक निर्माण है जो मुझे निम्नलिखित की तरह कुछ करने की अनुमति देगा:

SELECT whatever WHERE col1,col2 IN ((val1, val2), (val1, val2), ...)

मैं ऐसे डेटा का चयन करना चाहता हूं जहां दो कॉलम जोड़े के सेट में हों।

यदि संभव हो तो, एक उप-वर्ग का उपयोग करने से बचना चाहूंगा।

जवाबों:


49

क्या SQL में एक निर्माण है जो मुझे निम्नलिखित की तरह कुछ करने की अनुमति देगा:

हां, जैसा आपने लिखा है, लगभग वैसा ही है। बस col1, col2कोष्ठकों के अंदर रखें:

-- works in PostgreSQL, Oracle, MySQL, DB2, HSQLDB 
SELECT whatever 
FROM t                               --- you missed the FROM
WHERE (col1, col2)                    --- parentheses here
       IN ((val1a, val2a), (val1b, val2b), ...) ;

यदि आप किसी DBMS में इसे आज़माते हैं, तो आप पा सकते हैं कि यह काम नहीं करता है। क्योंकि सभी DBMS SQL मानक (विकसित) की सभी विशेषताओं को लागू नहीं करते हैं। यह ओरेकल, MySQL, Postgres, DB2 और HSQLDB के नवीनतम संस्करणों में काम करता है (यह MySQL में अच्छी तरह से अनुकूलित नहीं किया गया था और अनुक्रमित का उपयोग नहीं करता है, इसलिए इसे वहां से बचना चाहिए जब तक कि उन्होंने इसे 5.7 में तय नहीं किया)।

INऑपरेटर के बारे में MySQL दस्तावेज़ीकरण देखें और पंक्ति निर्माणकर्ताओं के बारे में दस्तावेज़ीकरण पोस्ट करें । कोष्ठकों में दो * (या अधिक) मानों को पंक्ति-निर्माता कहा जाता है ।

अन्य तरीके जो समान विचार व्यक्त करते हैं:

-- works in PostgreSQL, DB2
SELECT whatever 
FROM t 
WHERE (col1, col2) 
       IN ( VALUES (val1a, val2a), (val1b, val2b), ...) ;

SELECT t.whatever 
FROM t 
  JOIN 
    ( VALUES (val1a, val2a), (val1b, val2b), ...) AS x (col1, col2)
      ON (x.col1, x.col2) = (t.col1, t.col2) ;

दोनों Postgres और DB2 (afaik) में काम करते हैं। पिछले एक SQL सर्वर में काम करने के लिए भी संशोधित किया जा सकता है:

-- works in PostgreSQL, DB2, SQL Server
SELECT t.whatever 
FROM t 
  JOIN 
    ( VALUES (val1a, val2a), (val1b, val2b), ...) AS x (col1, col2)
      ON  x.col1 = t.col1
      AND x.col2 = t.col2 ;

पहले (अस्थायी या स्थायी) तालिका में मानों को रखकर इसे हर जगह काम करने के लिए संशोधित किया जा सकता है:

-- works everywhere
CREATE TABLE values_x
( col1  ...,
  col2  ...) ;

-- use appropriate for the DBMS syntax here
INSERT INTO values_x (col1, col2)
VALUES (val1a, val2a), (val1b, val2b), ... ;

SELECT t.whatever 
FROM t 
  JOIN values_x  x 
      ON  x.col1 = t.col1
      AND x.col2 = t.col2 ;

DROP TABLE values_x ;

और वहाँ हमेशा एक लंबा रास्ता है या INएक लंबी अभिव्यक्ति के साथ परिवर्तित ORकरना चाहिए कि हर जगह काम करना चाहिए:

-- works in all SQL DBMS
SELECT whatever 
FROM t  
WHERE col1 = val1a AND col2 = val2a
   OR col1 = val1b AND col2 = val2b
   ---
   ;

*: यह वास्तव में सिर्फ एक मूल्य हो सकता है, साथ में ROW(v), पोस्टग्रेज डॉक्स देखें।


मैं कहाँ के बारे में प्रलेखन पा सकते हैं WHERE (x, y) IN (a,b)? मैं MySql का उपयोग कर रहा हूं। शायद मुझे नहीं पता कि इस निर्माण को क्या कहा जाता है।
रॉबर्ट रोचा

1
@RobertRocha ने मेरे द्वारा जोड़े गए लिंक देखें। इसे एक पंक्ति निर्माता कहा जाता है: MySQL:IN और पोस्टग्रेज: रो कंस्ट्रक्टर्स
ypercubeᵀᴹ

वहाँ भी है WHERE EXISTS (SELECT t.col1, t.col2 [FROM DUAL] INTERSECT VALUES(val1, val2), (…, …), …)
एंड्री एम

-4
SELECT * 
FROM   dbo.Table1 A
WHERE  (CAST(Column1 AS VARCHAR(max)) + '-' + CAST(Column2 AS varchar(max)))
NOT IN (SELECT (CAST(Column1 AS VARCHAR(max)) 
                + '-' 
                + CAST(Column2 AS varchar(max))) 
        FROM Table2)

2
यह मज़बूती से काम नहीं करने वाला है
a_horse_with_no_name

2
हाँ। अक्षमता के अलावा, यह 'a-b', 'c'और के बीच अंतर करने में सक्षम नहीं होगा 'a', 'b-c'। और यह किसी भी प्रकार के लिए बुरी तरह से विफल हो जाएगा जिसे परिवर्तित नहीं किया जा सकता है varchar(max)
ypercube y
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.