总结与问题
我最近问了一个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
- 从
t
中读取所有行。 - 计算整个表
t
中每个id
的最大处理
。 - 计算每个
id
的outcome = 1
的行数。
第二个
select
id,
max(treatment) as ever_treated,
count(*) as count
from t
where outcome = 1
group by id
- 从
t
中读取行的子集,其中outcome = 1
。 - 计算表子集
t
中每个id
的最大处理
。 - 计算子集中每个
id
的行数(已过滤)。
就结果而言,只有#2 和#3 是重要的。如您所见,#3 是等价的,但 #2 不是。
关于sql - PostgreSQL 中的 WHERE 和 FILTER (WHERE) 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69339366/