[英]SQL select with “IN” subquery returns no records if the sub-query contains NULL
[英]SQL return exactly one row or null in a select sub-query
在Oracle中,是否有可能在select语句中包含一个子查询,如果该子查询仅返回一行,则该查询返回一列;如果该子查询未返回一行或多于一行,则返回null。
例:
SELECT X,
Y,
Z,
(SELECT W FROM TABLE2 WHERE X = TABLE1.X) /* but return null if 0 or more than 1 rows is returned */
FROM TABLE1;
谢谢!
如何以不同的方式去做呢? 一个简单的带有子查询的LEFT OUTER JOIN应该可以实现您想要的:
SELECT T1.X
,T1.Y
,T1.Z
,T2.W
FROM TABLE1 AS T1
LEFT OUTER JOIN (
SELECT X
,W
FROM TABLE2
GROUP BY X,W
HAVING COUNT(X) = 1
) AS T2 ON T2.X = T1.X;
这只会返回恰好具有1个X实例的项目,并在适当时将LEFT OUTER JOIN JOIN返回表中(不匹配为NULL)。
这也是ANSI兼容的,因此性能非常好。
如果您可以在W
列上应用聚合函数( MIN
或MAX
),那么除了CASE
解决方案或将内联子查询重写为外部联接之外,这还可以工作:
SELECT X,
Y,
Z,
(SELECT MIN(W) FROM TABLE2 WHERE X = TABLE1.X HAVING COUNT(*) = 1) AS W
FROM TABLE1;
SELECT
X, Y, Z, (SELECT W FROM TABLE2 WHERE X = TABLE1.X HAVING COUNT(*) = 1)
FROM
TABLE1;
我的答案是:不要使用子选择(除非您确定...)
不需要,也不是一个好主意,因为有两件事,所以在此处使用如PlantTheIdea所述的子选择
交代:
subselect表示:
对主选择结果集的每一行进行一次选择。 即,如果您获得1000行,那么您在数据库系统中还将获得1000个(小)select statemts(在这里忽略优化器)
和(!)
使用子选择,您有很大的机会隐藏(或覆盖)繁重的数据库或选择问题。 这意味着:您只希望没有(NULL)或只有一排(完全)的行(都可以通过[left external]联接轻松解决)。 如果您的子选择中有多个错误,则SQL错误指出
“ HAVING COUNT(X)= 1”当然正确,存在较小(或不小的)问题,那就是:“为什么计数多于一行?”
我花了数小时的时间寻找这样的工作环境,最后结果是“如果您确实确定,请不要这样做……”
我看到这与“具有”相反
...
HAVING date=max(date) -- depends on sql dialect
要么
where date = select max(date) from same_table
在我的最后一个示例中,我再次想指出:如果您到达这里多于一行(都从今天开始; ..),则存在数据库问题-例如,您应该使用时间戳记
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.