假设您有Accounts
表,其中ID
列是PK,TaxID+AccountNumber
是唯一约束:
select * from Accounts where ID in (100, 101)
现在您想使用自然键进行类似的查询:
select * from Accounts
where {TaxID, AccountNumber} in
({"0123456", "2000897"}, {"0125556", "2000866"})
所以这涉及元组并且看起来非常合理。有可能用ANSI SQL表达某种方式吗?也许在某些特定的SQL扩展?如果没有,为什么(会欣赏任何推测)?
答案 0 :(得分:3)
如果您使用的是T-SQL,那么看起来有点像您的假设查询的选项就是使用表格文字,如下所示:
select *
from Accounts a
inner join (values('0123456', '2000897'),('0125556', '2000866'))
as v(TaxID, AccountNumber)
on a.TaxID = v.TaxID and a.AccountNumber = v.AccountNumber
在此创建一个名为v
的表格文字,其中包含字段TaxID
和AccountNumber
。现在,您可以在两个字段上加入表格文字以获得所需的结果。需要注意的是,表格文字只能包含1000行。您可以在this page上阅读有关表格文字的T-SQL支持的更多信息。
编辑:this page表示此构造也适用于PostgreSQL。
答案 1 :(得分:3)
这两种语法都是有效的ISO / ANSI Full SQL-92语法:
SELECT a.*
FROM Accounts a
INNER JOIN
( VALUES('0123456', '2000897'), ('0125556', '2000866')
) AS v(TaxID, AccountNumber)
ON (a.TaxID, a.AccountNumber) = (v.TaxID, v.AccountNumber)
SELECT *
FROM Accounts a
WHERE (a.TaxID, a.AccountNumber) IN
( VALUES ('0123456', '2000897'), ('0125556', '2000866') )
但我认为它们中的任何一个都不适用于任何当前的DBMS。
这也是有效的完整SQL-92语法(由于NATURAL JOIN
,它在SQL-Server 2008中不起作用):
SELECT a.*
FROM Accounts a
NATURAL JOIN
( VALUES('0123456', '2000897'), ('0125556', '2000866')
) AS v(TaxID, AccountNumber)
这也是有效的SQL(不确定它是否在92规范或更高版本中) - 并且就是你所拥有的(但使用括号,而不是大括号)。
它受MySQL,Postgres,DB2(但不是SQL Server)的支持:
SELECT a.*
FROM Accounts a
WHERE (TaxID, AccountNumber) IN
( ('0123456', '2000897'), ('0125556', '2000866') )
;
在DBA.SE中也有类似的问题,还有其他各种方法来制定这个问题:
的 selecting where two columns are in a set 强>
答案 2 :(得分:2)
小心如何代表这一点。 Shark的答案会有效,但会返回
TaxID AccountNumber
1234 8765
1234 7654
2345 8765
2345 7654
可能不是您想要的...例如,如果您只需要税号1234的帐号8765和税号2345的7654,则需要这样的WHERE子句:
WHERE (taxId'1234' and accountnumber='8765') OR
(taxid='2345' and accountNumber='7654')
答案 3 :(得分:2)
粗略的方法是将2个值连接在一起..
e.g。
SELECT *
FROM Accounts
WHERE CAST(TaxID AS VARCHAR(10)) + '-' + CAST(AccountNumber AS VARCHAR(10))
IN ('0123456-2000897', '......', ....)
但是,在例如SQL Server,这将无法使用索引。
您可以添加一个计算列,将两个值组合成1,然后匹配:
SELECT * FROM Accounts WHERE MyComputedColumn IN ('0123456-2000897', ....)
或者,您可以这样做:
SELECT a.*
FROM Accounts a
JOIN
(
SELECT '0123456' AS TaxID, '2000897' AS AccountNumber
UNION ALL
SELECT '0125556', '2000866'
) x ON a.TaxID = x.TaxID AND a.AccountNumber = x.Number
答案 4 :(得分:1)
在Oracle SQL中,您只需将括号替换为原始帖子中的大括号“{}”(第二个示例)。可能不是ANSII标准,但它很接近,而且工作正常。
建议不要连接这些值,即使使用不常见的分隔符,也总是会有一些微小的风险,即错误地匹配自由输入的文本值。最好不要养成这个习惯。