如何检查子查询是否恰好具有一个完全不同的结果和一个指定的值?


10

我发现自己写了以下内容:

select 'yes' 
where exists(select * from foo where val=1)
and not exists(select * from foo where val<>1);

并且想知道是否有一种更简洁的方法而不牺牲太多的可读性。

我找到了一种发布答案的方法,但我对此并不完全满意,并且会对替代方法非常感兴趣

在这种情况下val,内部是唯一的foo-没有重复项


我是否正确理解你想要的是一个子查询的结果行?
Erwin Brandstetter 2012年


您在标题中提到的那个。我不确定这应该是“与众不同”之后还是之前的结果。
Erwin Brandstetter 2012年

是的,那是一个:)我在回答中的子查询时相当混乱-您的子查询更加具体和灵活,例如,您也可以使用count(distinct val),尽管在我的实际案例中这没什么关系
杰克说尝试topanswers.xyz 2012年

Answers:


8

简洁,快速(特别是有很多行),我最喜欢的是可读性,并且也可以与dupes一起使用:

SELECT count(*) = 1 AND min(val) = 1 FROM foo;

返回TRUE/ FALSE..或NULL- 在带有的一行的情况下val IS NULL,因为count()从不返回NULL或没有行。

1由于您的示例,示例中的第二个恰好与第一个相同。


问题中的查询失败,并带有NULL值。考虑简单的演示:

CREATE TABLE foo (id int, val int);
INSERT INTO foo VALUES (1, 1),(2, NULL);

SELECT 'yes' 
WHERE      EXISTS(SELECT * FROM foo WHERE val =  1)
AND    NOT EXISTS(SELECT * FROM foo WHERE val <> 1);

IS DISTINCT FROM可以解决此问题,但是如果出现重复,仍然会失败val-您已经排除了这种情况。


您的答案很好。
返回'yes'/无行。

不过,我更喜欢这种较短的形式。不要忘记PostgreSQL(与Oracle不同)具有适当的boolean类型

SELECT array_agg(val) = array[1] FROM foo;

返回TRUE/ FALSE/ NULL



5

@Erwin答案的变化形式。完全没有COUNT(),只有MIN()MAX()。大表和(不是您的情况下)重复表可能会更有效val

SELECT MIN(val) = 1 AND MAX(val) = 1 FROM foo;

+1谢谢。当然,它对null和重复项的处理方式也有所不同(如果有的话)
杰克说请尝试topanswers.xyz 2012年

@杰克:是的。您的表格是否有空值?还是您想针对这两种情况(有或没有)都给出答案?
ypercubeᵀᴹ

没有我不会-我可以使用:)
杰克说尝试topanswers.xyz 2012年

将是快于与匹配的索引更大的表,但执行相同的在不存在这样的索引-测试查询结果时等。
Erwin Brandstetter,2012年


1

这将返回truefalse或者结果为空:

 select j.val is null 
 from foo left join foo as j on j.val <> foo.val 
 where foo.val = 1 limit 1;

乍一看,false如果foowhere中有值,这似乎不会返回val<>1
杰克说请尝试topanswers.xyz 2012年

@JackDouglas哦,对不起。我第一次错了任务。固定。
grayhemp 2012年

有效-除非具有NULL在这种情况下不排除的值。
Erwin Brandstetter,2012年

我认为@ErwinBrandstetter NULL可以解决IS [NOT] DISTINCT FROM
grayhemp 2012年

1
@ grayhemp:在这种情况下不是。LEFT JOIN foo j ON j.val <> foo.val无法检测j.val IS NULL到以开始的行。如果将其包括在内,ON j.val IS DISTINCT FROM foo.val则需要检查已j定义的另一列NOT NULL以区分这两种情况。但是没有定义其他列。
Erwin Brandstetter,2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.