繁体   English   中英

SQL在选择子查询中仅返回一行或空值

[英]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列上应用聚合函数( MINMAX ),那么除了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM