Sql 如果所有列值均为true,则返回true

Sql 如果所有列值均为true,则返回true,sql,postgresql,aggregate-functions,exists,boolean-logic,Sql,Postgresql,Aggregate Functions,Exists,Boolean Logic,在PostgreSQL中,有没有一种更快的方法可以对多行执行if 假设我有一张桌子 ticket | row | archived 1 | 1 | true 1 | 2 | true 1 | 3 | true 2 | 1 | false 2 | 2 | true 我有没有办法在ticket=列的下面做一个if语句? 因此,如果ticket=1,则为真,因为 true && true && tr

在PostgreSQL中,有没有一种更快的方法可以对多行执行if

假设我有一张桌子

ticket | row | archived
1      | 1   | true
1      | 2   | true
1      | 3   | true
2      | 1   | false
2      | 2   | true
我有没有办法在ticket=列的下面做一个if语句? 因此,如果ticket=1,则为真,因为

true && true && true = true
如果票证=2,则为假,因为

false && true = false
还是我应该坚持下去

SELECT ( (SELECT COUNT(*) FROM table WHERE ticket = 1)
       = (SELECT COUNT(*) FROM table WHERE ticket = 1 AND archived = true) )

比如说:

select not exists (select 1 from table where ticket=1 and not archived)
我认为这可能比比较计数更有利,因为这是一个
计数
,实际上您需要知道的是该票据是否存在任何
FALSE
行。我认为在
ticket
上创建部分索引可能会非常快

聚合函数 简单、简短、清晰:

SELECT bool_and(archived)
FROM   tbl
WHERE  ticket = 1;
:

如果所有输入值均为true,则为true,否则为false

子查询表达式 喜欢

更快。但是您必须另外检查是否存在任何
ticket=1
的行,否则对于不存在的ticket,您将得到不正确的结果:

SELECT EXISTS (SELECT 1 FROM tbl WHERE ticket=1)
       AND NOT
       EXISTS (SELECT 1 FROM tbl WHERE ticket=1 AND archived = FALSE);
指数 这两种形式都可以并将使用如下索引:

CREATE index tbl_ticket_idx ON tbl (ticket);
。。这使得两者都很快,但是
存在
查询速度更快,因为一旦找到第一个匹配行,此表单就可以停止扫描。这两个查询之间几乎没有任何区别,每个票据只有几行,但是每个票据有很多行,这两个查询之间有很大的区别

要使用第9.2页中的仅索引扫描,您需要使用以下格式:

CREATE index tbl_ticket_archived_idx ON tbl (ticket, archived);
无论在任何情况下,在大多数情况下,还是在任何版本的PostgreSQL中,这个都是更好的。由于,将
布尔值
添加到索引中的
整数
将不会使索引增长。几乎不需要任何成本就能增加效益

但是,索引列阻止热(仅堆元组)更新。比如说,
UPDATE
只更改
存档的列。如果列未被任何索引(以任何方式)使用,则可以热更新该行。否则,此快捷方式无法使用。有关热更新的更多信息:


这完全取决于您的实际工作负载。

Count如果是9.2之前版本的PostgreSQL,则不会使用索引。最近才知道。@JayC:当然count()可以使用索引
从foo中选择count(*),其中某些列=1
可以在某些列上使用索引(如果该列不返回太多行)
count()
如果您正在计算一个表中的所有行(没有任何限制)@a_horse_和_no_name,则不会使用索引-哦,谢谢您的澄清!我对最近的问题有点好奇,我看到你也对这个问题发表了评论。@a_horse_,没有名字:你是对的;我不该让迈克把我弄糊涂;-)绝对是一个干净的解决方案!好奇性能如何,它能利用9.2中仅索引扫描的优势吗?@Mike:我挖得更深一些,运行了一些测试,并在我的答案中添加了一点关于索引和性能的内容。@MikeChristensen我感谢您抽出时间回答!不过我还是接受了欧文的答案,因为短得多的代码在我的查询中会更好!对性能的影响应该不会太大,我不希望此查询在每张票据上运行超过几行。谢谢大家@mouckatron:我添加了一些关于热门更新的内容。如果你有大量的
更新
s,你可能会感兴趣。@ErwinBrandstetter你对Postgres的了解总是让我印象深刻。到现在为止,我对你的几十个答案投了赞成票。
CREATE index tbl_ticket_archived_idx ON tbl (ticket, archived);