这可能是一个愚蠢的问题,我怀疑我无法做到这一点,但是SQL中是否有一种结构可以让我执行以下操作:

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


我想选择一组成对的两列数据。

如果可能的话,我想避免使用子查询。

#1 楼


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标准的所有功能。这在Oracle,MySQL,Postgres,DB2和HSQLDB的最新版本中有效(在MySQL中没有很好地优化并且不使用索引,因此除非在5.7中对其进行了修复,否则应避免在其中使用)。

请参阅有关IN运算符的MySQL文档和有关Row构造函数的Postgres文档。括号中的两个*(或更多)值称为行构造器。

表达相同想法的其他方式:

-- 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 Server中工作:

-- 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)的一个值,请参阅Postgres文档。

评论


在哪里可以找到有关WHERE(x,y)IN(a,b)的文档?我正在使用MySql。也许我不知道这个结构叫什么。

– Robert Rocha
17-10-9在2:03

@RobertRocha看到我添加的链接。它被称为行构造函数:MySQL:IN和Postgres:行构造函数

–超立方体ᵀᴹ
17-10-9在6:28



还有WHERE EXISTS(选择t.col1,t.col2 [FROM DUAL]相交值(val1,val2),(…,…),…)。

– Andriy M
18年1月26日在13:46

#2 楼

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)


评论


那将无法可靠地工作

– a_horse_with_no_name
18年1月25日在10:03

是。除了效率低下,它也无法区分“ a-b”,“ c”和“ a”,“ b-c”。对于任何无法转换为varchar(max)的类型,它都会惨遭失败。

–超立方体ᵀᴹ
18年1月25日在10:31