2013-04-11 19 views
5

Spójrzmy na przykład Oracle SQL, który działa perfekcyjnie: daneT-SQL równoważna Oracle SQL gdzie klauzuli z wieloma kolumnami

Sample:

SQL> create table test (a number, b number); 
SQL> insert into test values(1, 1); 
SQL> insert into test values(1, 2); 
SQL> insert into test values(1, 3); 
SQL> insert into test values(1, 4); 
SQL> insert into test values(1, 5); 
SQL> insert into test values(2, 1); 
SQL> insert into test values(2, 2); 
SQL> insert into test values(2, 3); 
SQL> insert into test values(2, 4); 
SQL> insert into test values(2, 5); 
SQL> insert into test values(4, 1); 

SQL> select * from test; 

     A   B 
---------- ---------- 
     1   1 
     1   2 
     1   3 
     1   4 
     1   5 
     2   1 
     2   2 
     2   3 
     2   4 
     2   5 
     4   1 

Zapytanie:

SQL> select * from test where (a, b) in (select 1, 4 from dual); 

     A   B 
---------- ---------- 
     1   4 

tutaj sql-fiddle: http://www.sqlfiddle.com/#!4/8375e/3/0

Proste pytanie: czy istnieje odpowiednik w MS SQL powyższej klauzuli "where (a, b)"? Rozglądałem się w Google, MS Docs i nic do tej pory ...

+0

http://stackoverflow.com/questions/4452539/sql-server-in-clause-with-multiple-fields – Habib

+0

Jak to działa w Oracle? Czy to jest to samo co 'wybierz * z testu gdzie a = 1 i b = 4;'? Jaka jest zatem korzyść? –

+0

N.B: '(a, b)' jest nazywany "wyrażeniem wartości wiersza" lub krotką. To może pomóc w googlowaniu. –

Odpowiedz

0

Co powiecie na poniższe zapytanie, które obsługuje serwer sql; i myślę a=1 and b=4 daje ten sam wynik w serwerze SQL odpowiednik kwerendy oracle .:

select 
    * 
from 
    test 
where 
    a=1 and 
    b=4; 
+1

Czy to jest to samo, co zapytanie Oracle (nie wiem)? Poda jeden rekord jako pozostałe odpowiedzi, ale jeśli wstawisz inny z 'a = 4, b = 1', otrzymasz dwa rekordy zamiast jednego. http://www.sqlfiddle.com/#!3/24f87/5/1 –

+0

Tak, moja odpowiedź zawiera tylko 1 rekord. W wyroczni również wyjście jest jednym rekordem (jak wspomniał). – TechDo

+0

Tak, to zapytanie nie jest poprawne. Zgodnie ze standardem SQL '(a, b) = (1, 4)' jest równoważne '(a = 1) AND (b = 4)'. To uwzględnia predykat 'IN' i podselekcję równie dobrze. Twój predykat jest równoważny '(1 = OR 1 = b) ORAZ (4 = a OR 4 = b)' –

5

Podczas SQL Server ma Table Value Constructor, które mogą być stosowane do niektórych przypadków użycia, SQL Server nie obsługuje SQL standardowej wartości wiersza wyrażenia i predykaty wyprowadzone z wyrażenia wartości wierszy do ogólnego użytku (jeszcze). trzeba będzie uciekać się do pół-łączenia swoją podkwerenda wykorzystaniem równoważnego EXISTS klauzuli:

to:

select * from test where (a, b) in (select 1, 4 from dual); 

jest równoznaczne z tym (patrz SQLFiddle demo):

select * from test where exists (
    select * from (
    select 1, 4 -- Replace with "real" subselect 
) t(a, b) 
    where test.a = t.a and test.b = t.b 
) 

Albo trochę bardziej ogólnie, używając wspólnego wyrażenia tabelowego (zobacz SQLFiddle demo):

with t(a, b) as (
    select 1, 4 -- Replace with "real" subselect 
) 
select * from test where exists (
    select * from t 
    where test.a = t.a and test.b = t.b 
) 
+0

Oto przykład [Połącz problem] (http://connect.microsoft.com/SQLServer/feedback/details/299231/add-support-for-ansi-standard-row-value-constructors), jeśli masz ochotę głosować na to. –

+0

@Damien_The_Unbeliever: Dzięki za link. Będę! –

Powiązane problemy