是否可以在SQL查询的WHERE
子句中比较元组(thanks,a_horse_with_no_name)?这样,我可以转换它:
/* This is actually a sub-sub-sub-query in the middle *
* of an incredibly complex stored procedure. */
SELECT ISNULL(SUM(DT.DetailField), 0)
FROM DetailTable DT
WHERE DT.ForeignKey = ...
AND EXISTS (/* I know this sub-sub-sub-sub-query *
* will return at most one row. */
SELECT 'X'
FROM HeaderTable HT
WHERE HT.HeaderKey = DT.HeaderKey
AND HT.HeaderField1 = ...
AND HT.HeaderField2 = ...)
进入类似的事情:
SELECT ISNULL(SUM(DetailField), 0)
FROM DetailTable DT
WHERE DT.ForeignKey = ...
AND (SELECT HT.HeaderField1, HT.HeaderField2
FROM HeaderTable HT
WHERE HT.HeaderKey = DT.HeaderKey) = (..., ...)
答案 0 :(得分:5)
写作
AND (SELECT HT.HeaderField1, HT.HeaderField2 FROM HeaderTable HT WHERE HT.HeaderKey = DT.HeaderKey) = (..., ...)
肯定是可能的。至少使用Oracle和PostgreSQL
如果您不确定子选择是否返回多行,您甚至可以将=
更改为IN
答案 1 :(得分:5)
您正在寻找的是内部联接:
SELECT ISNULL(SUM(DetailField), 0)
FROM DetailTable DT
INNER JOIN HeaderTable HT ON HT.HeaderKey = DT.HeaderKey
WHERE DT.ForeignKey = ...
AND HT.HeaderField1 = ...
AND HT.HeaderField2 = ...)
答案 2 :(得分:2)
您好像在尝试比较记录而不是表。事实上,您正在比较查询的结果。
完全可以使用Oracle和MySQL。以下查询有效并执行以下任务:
SELECT (SELECT foo, bar FROM wathever) = (SELECT fuu, baz FROM another);
它将比较一对一的字段,如果它们全部匹配则返回1(如果它们不匹配,则返回0)。如果子查询返回多行,则会引发SQL错误。此表达式也可以在WHERE子句中的其他地方使用。
正如@tsionyx指出的那样,在PostgreSQL中,子查询不能返回多个列。返回行值类型是可行的:
SELECT (SELECT ROW(foo, bar) FROM wathever) = (SELECT ROW(fuu, baz) FROM another);
答案 3 :(得分:1)
Goran的回答对我来说最好,我投了赞成票。只是为了添加另一个选项,因为您使用的是SQL Server,从子查询中获取多个列的灵活方法是outer apply
。您可以比较两个值(元组),如:
select *
from SomeTable t1
outer apply
(
select *
from SomeOtherTable t2
where t1.Stuff = t2.Unit
) sub1
outer apply
(
select *
from YetAnotherTable t3
where t1.Stuff = t3.jetser
) sub2
where sub1.col1 = sub2.col1
and sub1.col2 = sub2.col2