kümede iki sütunun nerede olduğunu seçme


35

Bu aptalca bir soru olabilir ve şüphem bunu yapamayacağım, ancak SQL'de aşağıdaki gibi bir şey yapmama izin verecek bir yapı var:

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

İki sütunun çiftler halinde olduğu verileri seçmek istiyorum.

Mümkünse bir alt sorgu kullanmaktan kaçınmak istiyorum.

Yanıtlar:


48

SQL'de aşağıdaki gibi bir şey yapmamı sağlayacak bir yapı var mı:

Evet, aynen yazdığınız gibi. Sadece col1, col2parantez içine koyun :

-- 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), ...) ;

Ancak bir DBMS'de denerseniz, çalışmadığını görebilirsiniz. Çünkü tüm DBMS'ler (gelişen) SQL standardının tüm özelliklerini uygulamamıştır. Bu, Oracle, MySQL, Postgres, DB2 ve HSQLDB'nin en son sürümlerinde çalışır (MySQL'de iyi bir şekilde optimize edilmedi ve dizin kullanmıyor, bu yüzden 5.7'de düzeltilmeden kaçınılmalıdır).

Row yapıcılar hakkında INişleç ve Postgres belgeleri hakkında MySQL belgelerine bakın . Parantez içindeki iki * (veya daha fazla) değere satır kurucusu adı verilir .

Aynı fikri ifade eden diğer yollar:

-- 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) ;

Her ikisi de Postgres ve DB2'de (afaik) çalışıyor. Sonuncusu da SQL Server'da çalışmak üzere değiştirilebilir:

-- 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 ;

Ayrıca, değerleri önce (geçici veya kalıcı) bir tabloya yerleştirerek her yerde çalışmak üzere değiştirilebilir:

-- 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 ;

Ve her zaman uzun yol vardır ya da her yerde işe yarayacak INuzun bir ifadeye ORdönüşür:

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

*: Aslında, sadece bir değer olabilir ROW(v), bkz. Postgres docs.


Dokümanları nerede bulabilirim WHERE (x, y) IN (a,b)? MySQL kullanıyorum. Belki de bu yapının ne dendiğini bilmiyorum.
Robert Rocha,

1
@RobertRocha eklediğim bağlantıları gör. Buna bir satır yapıcısı denir: MySQL:IN ve Postgres: Row Yapıcılar
ypercubeᵀᴹ

Bir de var WHERE EXISTS (SELECT t.col1, t.col2 [FROM DUAL] INTERSECT VALUES(val1, val2), (…, …), …).
Andriy M

-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
Bu güvenilir bir şekilde çalışmayacak
a_horse_with_no_name

2
Evet. Verimlilik dışında, 'a-b', 'c've arasındaki farkı ayırt edemez 'a', 'b-c'. Ve dönüştürülemeyen herhangi bir tür için sefilce başarısız olur varchar(max).
ypercubeᵀᴹ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.