sql - PostgreSQL 中的 WHERE 和 FILTER (WHERE) 有什么区别?

标签 sql postgresql where-clause

总结与问题

我最近问了一个Postgres-related question在 SO 上,得到了几个不同的查询答案,帮助我得到了我想要的结果。他们都工作了,得到了正确的结果,并且都有非常相似的代码。但是有一行是不同的:一个答案使用 WHERE 子句来挑选出我要求的内容,而另一个使用 FILTER (WHERE ...)。这两者有什么区别?

背景细节

出于好奇,我问过的 table 就是这张:

+--+---------+-------+
|id|treatment|outcome|
+--+---------+-------+
|a |1        |0      |
|a |1        |1      |
|b |0        |1      |
|c |1        |0      |
|c |0        |1      |
|c |1        |1      |
+--+---------+-------+

我想要这样的东西:

+-----------------------+-----+
|ever treated           |count|
+-----------------------+-----+
|0                      |1    |
|1                      |3    |
+-----------------------+-----+

我得到了两个有效的答案。这是来自@ErwinBrandstetter 的第一个:

SELECT ever_treated, sum(outcome_ct) AS count
FROM  (
   SELECT id, 
          max(treatment) AS ever_treated, 
          count(*) FILTER (WHERE outcome = 1) AS outcome_ct
   FROM t
   GROUP  BY 1
   ) sub
GROUP  BY 1;

这是@Heidiki 和第二个:

    select subq.ever_treated, sum(subq.count) as count
    from (select id, 
          max(treatment) as ever_treated, 
          count(*) as count from t where outcome = 1 
          group by id) as subq 
    group by subq.ever_treated;

在我(无可否认的新手)看来,两者之间的主要区别在于,在前者中,您会看到:

count(*) FILTER (WHERE outcome = 1) AS outcome_ct

而在后者中,你有这个:

count(*) as count from t where outcome = 1

我正在查看一些文档,我看到 FILTER 在聚合级别上工作,而 WHERE 可能不是,但我仍然迷路了凭直觉,尤其是当它适用于我的 table 时。

那么这里有什么区别呢?

最佳答案

子查询不等价:

第一个

SELECT
  id, 
  max(treatment) AS ever_treated, 
  count(*) FILTER (WHERE outcome = 1) AS outcome_ct
FROM t
GROUP BY 1
  1. t 中读取所有行。
  2. 计算整个表 t 中每个id 的最大处理
  3. 计算每个 idoutcome = 1 的行数。

第二个

select
  id, 
  max(treatment) as ever_treated, 
  count(*) as count 
from t
where outcome = 1 
group by id
  1. t 中读取行的子集,其中 outcome = 1
  2. 计算表子集 t 中每个id 的最大处理
  3. 计算子集中每个 id 的行数(已过滤)。

就结果而言,只有#2 和#3 是重要的。如您所见,#3 是等价的,但 #2 不是。

关于sql - PostgreSQL 中的 WHERE 和 FILTER (WHERE) 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69339366/

相关文章:

sql - 选择主值处于禁用状态且子值处于事件状态的行

PostgreSQL:列必须出现在 GROUP BY 子句中或在聚合函数中使用

sql - 在 SQL 中是否可以返回具有属性名称然后是值的第一行

mysql where 子句不起作用

mySQL 用 WHERE 更新

mysql - 无法在 WHERE 子句中使用 SELECT 子句的别名

mysql - 为什么我不能以这种方式创建表?

python - sqlite3 数据类型中的拼写错误但仍然有效,为什么?

java - 使用 ps.setObject 而不是 SQL 准备语句的类型特定方法会影响性能吗?

postgresql - EJB3.1 注入(inject) JSF2.1 托管 bean 的不确定行为