SQL在select子查询中只返回一行或null
在Oracle中,是否可以在select语句中包含子查询,如果子查询只返回一行,则该语句返回一列;如果子查询未返回任何行或返回多行,则该语句返回null 例如:SQL在select子查询中只返回一行或null,sql,oracle,subquery,Sql,Oracle,Subquery,在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; 谢谢 除了一个案例解决方案或将内联子查询重写为外部联接之外,如果
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;
谢谢 除了一个
案例
解决方案或将内联子查询重写为外部联接之外,如果您可以在W
列上应用聚合函数(MIN
或MAX
):
SELECT
X, Y, Z, (SELECT W FROM TABLE2 WHERE X = TABLE1.X HAVING COUNT(*) = 1)
FROM
TABLE1;
SELECT X,
Y,
Z,
(SELECT MIN(W) FROM TABLE2 WHERE X = TABLE1.X HAVING COUNT(*) = 1) AS W
FROM TABLE1;
换一种方式怎么样?带有子查询的简单左外部联接应该满足您的要求:
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;
这将只返回正好有一个X实例的项,并在适当时将其返回到表中(将非匹配项保留为NULL)
这也是符合ANSI标准的,因此性能相当好。我的回答是:不要使用子选择(除非您确定…) 在这里使用PlantTheIdea提到的subselect没有必要,也不是一个好主意,因为有两个原因 解释: 子选择是指: 主选择结果集的每行一个选择。i、 e.如果您得到1000行,那么您的数据库系统中也会得到1000(小)select STATEMT(忽略优化器) 和(!) 通过子选择,您很有可能隐藏(或覆盖)大量数据库或选择问题。这意味着:您只需要一行(空)或一行(精确)(两者都可以通过[left outer]联接轻松解析)。如果您的子选择中有多个错误,那么SQL错误会指出这一点 “HAVING COUNT(X)=1”当然是正确的,但有一个小(或不小)问题,那就是:“为什么有多行的计数?” 我花了好几个小时找一个这样的工作,结果只是“如果你真的确定的话就不要做…” 我认为这与这样的“拥有”相反
...
HAVING date=max(date) -- depends on sql dialect
或
在我的最后一个例子中,我想再次指出:如果这里有多行(都是从今天开始的),那么您就有一个DB问题-您可以使用时间戳,例如,您可以使用case语句。。您尚未在subquery.derp中选择
X
!谢谢你。我也意识到没有必要分组,因为每个实例的返回值总是正好是1。很抱歉,这不会按原样运行。您需要聚合或一些窗口/分析函数wizadry。您不能只使用在.derp周围包含子句的选择x,w
。。。这就是我没有测试的结果,哈哈<代码>拥有
需要一个分组依据
@plantheldea这几乎可以工作,除了我得到额外的行,而不是与表1相同的行数。我尝试了其他类型的联接,但它们返回的行数都比表1略多或略少。这样做需要group by,当我执行group by时,会出现一个错误,指出“单行子查询返回多行”。可能值得一提的是,子查询的where子句有多个部分。表1和表2有几个字段是匹配行所必需的,而不仅仅是W。这不需要分组依据。
where date = select max(date) from same_table