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

mou*_*ron 14 sql postgresql boolean-logic exists aggregate-functions

在PostgreSQL中有一种更快的方法来基本上在几行中执行if吗?

说我有一张桌子

ticket | row | archived
1      | 1   | true
1      | 2   | true
1      | 3   | true
2      | 1   | false
2      | 2   | true
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以在ticket =的列下面做一个if语句?因此,ticket = 1的地方是真的

true && true && true = true
Run Code Online (Sandbox Code Playgroud)

并且ticket = 2将是假的,因为

false && true = false
Run Code Online (Sandbox Code Playgroud)

或者我应该坚持下去

SELECT ( (SELECT COUNT(*) FROM table WHERE ticket = 1)
       = (SELECT COUNT(*) FROM table WHERE ticket = 1 AND archived = true) )
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 16

聚合功能 bool_and()

简单,简洁,清晰.

SELECT bool_and(archived)
FROM   tbl
WHERE  ticket = 1;
Run Code Online (Sandbox Code Playgroud)

我在这里引用手册:

SELECT EXISTS (SELECT 1 FROM tbl WHERE ticket=1)
       AND NOT
       EXISTS (SELECT 1 FROM tbl WHERE ticket=1 AND archived = FALSE);
Run Code Online (Sandbox Code Playgroud)

子查询表达式EXISTS- 像@Mike提供的那样

快点.但是你必须另外检查是否ticket = 1存在任何存在的行,否则你将得到不存在的票证的错误结果:

CREATE index tbl_ticket_idx ON tbl (ticket);
Run Code Online (Sandbox Code Playgroud)

索引

两种形式都可以并且将使用如下索引:

CREATE index tbl_ticket_archived_idx ON tbl (ticket, archived);
Run Code Online (Sandbox Code Playgroud)

..这两个都很快,但EXISTS查询速度更快,因为一旦找到第一个匹配的行,这个表单就可以停止扫描.两个查询之间几乎没有任何区别,每个票证只有几行,但每张票证的许多行存在很大差异.

要在第9.2页中使用仅索引扫描,您需要一个表格的多列索引:

SELECT bool_and(archived)
FROM   tbl
WHERE  ticket = 1;
Run Code Online (Sandbox Code Playgroud)

这是一个更好的任何情况下,大多数情况下和PostgreSQL的任何版本.由于数据排列,添加booleaninteger索引中不会使指数增长的.几乎没有任何成本增加了好处.

但是,索引列会阻止HOT(Heap Only Tuple)更新.说,一个UPDATE只修改列archived.如果该列未被任何索引使用(以任何方式),则可以对该行进行HOT更新.否则,不能采用这种快捷方式.我在这个相关答案中写了更多有关HOT更新的内容.

因此,一如既往,这一切都取决于您的确切工作量.


Mik*_*sen 5

怎么样的:

select not exists (select 1 from table where ticket=1 and not archived)
Run Code Online (Sandbox Code Playgroud)

我认为这可能比比较计数更有利,因为count 可能会或可能不会使用索引,实际上您需要知道的是该票证是否存在任何 FALSE行.我认为只是创建一个部分索引ticket可能会非常快.

SQL小提琴