2009-09-25 17 views
12

में एसक्यूएल में tuples का उपयोग कर इस तरह एक डेटाबेस को देखते हुए:खंड

BEGIN TRANSACTION; 
CREATE TABLE aTable (
a STRING, 
b STRING); 
INSERT INTO aTable VALUES('one','two'); 
INSERT INTO aTable VALUES('one','three'); 
CREATE TABLE anotherTable (
a STRING, 
b STRING); 
INSERT INTO anotherTable VALUES('one','three'); 
INSERT INTO anotherTable VALUES('two','three'); 
COMMIT; 

मैं की

SELECT a,b FROM aTable 
WHERE (aTable.a,aTable.b) IN 
(SELECT anotherTable.a,anotherTable.b FROM anotherTable); 

जवाब 'एक' प्राप्त करने के लिए पंक्तियों के साथ कुछ करना चाहते हैं, 'तीन' , लेकिन मुझे "पास" मिल रहा है, ": वाक्यविन्यास त्रुटि"

क्या यह एसक्यूएल के किसी भी स्वाद में संभव है? (मैं स्क्लाइट का उपयोग कर रहा हूं)

क्या मैं सकल वैचारिक त्रुटि कर रहा हूं? और क्या?

उत्तर

18

अपने कोड काम करता है अगर आप PostgreSQL या Oracle में करते हैं। एमएस एसक्यूएल पर, यह समर्थित नहीं है

उपयोग करें:

SELECT a,b FROM aTable 
WHERE 
-- (aTable.a,aTable.b) IN -- leave this commented, it makes the intent more clear 
EXISTS 
(
    SELECT anotherTable.a,anotherTable.b -- do not remove this too, perfectly fine for self-documenting code, i.e.. tuple presence testing 
    FROM anotherTable 
    WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b 
); 

[संपादित करें]

बिना आशय का बताते हुए:

SELECT a,b FROM aTable 
WHERE  
EXISTS 
(
    SELECT * 
    FROM anotherTable 
    WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b 
); 

यह कुछ हद तक लंगड़ा है, एक से अधिक के लिए दशक, एमएस एसक्यूएल के पास अभी भी टुपल्स के लिए प्रथम श्रेणी का समर्थन नहीं है। टुपल निर्माण में अपने समान EXISTS निर्माण की तुलना में अधिक पठनीय तरीका है। बीटीडब्ल्यू, जॉइन भी काम करता है (टस्टर का कोड), लेकिन अगर आपको कुछ और लचीला और भावी सबूत चाहिए, तो EXISTS का उपयोग करें।

[संपादित करें] SQLite के

बोल, मैं हाल ही में इसके साथ dabbling कर रहा हूँ। हाँ, tuples में

+0

10 मिनट में निश्चित उत्तर! एसक्लाइट में काम नहीं करता है :-( ने –

+0

को वोट दिया और स्वीकार किया, भले ही यह स्क्लाइट में काम करता है, मैं इसे करने की सलाह नहीं दूंगा। यह आपके कोड के भविष्य के रखरखाव को भ्रमित करने के लिए बाध्य है। (नोट: आप भविष्य हैं रखरखाव, तो यह आप हैं जो उलझन में होंगे) – tster

+4

@tster - मैं किसी भी भ्रम के स्रोत को देखने में असफल रहा –

2

आप एक में शामिल होने का उपयोग कर सकते हैं:

SELECT aTable.a, aTable.b FROM aTable 
JOIN anotherTable ON aTable.a = anotherTable.a AND aTable.b = anotherTable.b 
+0

यह काम करता है। इसके अलावा उत्तर 5 मिनट में दिखाया गया है! अभी भी यह जानने में दिलचस्पी है कि मेरा प्रस्तावित कोड संभव है/निराशाजनक रूप से गलत है/जो भी हो? –

+0

हां, आप जिस तरह से समझते हैं उसमें लिखने की कोशिश कर रहे हैं, लेकिन इस समस्या को सेट सिद्धांत, एसक्यूएल के आधार का उपयोग करके अधिक स्वाभाविक रूप से हल किया जाता है। एसक्यूएल का एक बहुत ही सामान्य उपयोग उनको छेड़छाड़ करने के लिए दो तालिकाओं में शामिल होना है, जो आप करने की कोशिश कर रहे हैं। – RedFilter

+0

@ ऑर्बमन: आईएन अधिक सहज है; कई बार शामिल हों, बहुत अधिक कंप्यूटर-विज्ञान दिख रहा है। और यह एक भाषा से अधिक प्रथम श्रेणी के निर्माण को लेकर कुछ आसान करने में सक्षम होने के मामले में है (लगता है कि सी # के गुण बनाम जावा सेटटर/गेटर)। यदि आईएन एकल मूल्य के लिए काम करता है, तो मुझे लगता है कि यदि आप आरडीबीएमएस का उपयोग कर रहे हैं तो भी आप खुश होंगे और जोड़े गए मानों (टुपल्स) –

1

काम नहीं करता है एक अन्य विकल्प एक भी क्षेत्र में अपने 2-टपल बनाने के लिए संयोजन का उपयोग करना है:

SELECT a,b FROM aTable 
WHERE (aTable.a||'-'||aTable.b) IN 
(SELECT (anotherTable.a || '-' || anotherTable.b FROM anotherTable); 

... बस ध्यान रखें कि बुरी चीजें तब हो सकता है एक या बी में डिलीमीटर '-'

+1

इस समाधान का कोई अन्य नुकसान होगा: क्वेरी ऑप्टिमाइज़र ऐसे अभिव्यक्तियों के बारे में कारण नहीं दे सकता है और इसलिए क्वेरी को अनुकूलित नहीं कर सकता है। – iuzuz