Sql 如果所有列值均为true,则返回true
在PostgreSQL中,有没有一种更快的方法可以对多行执行if 假设我有一张桌子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
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);