【问题标题】:What's the difference between WHERE and FILTER (WHERE) in PostgreSQL?PostgreSQL 中的 WHERE 和 FILTER (WHERE) 有什么区别?
【发布时间】:2021-09-26 22:15:09
【问题描述】:

总结和问题

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

背景细节

为了好奇,我问的是这张桌子:

+--+---------+-------+
|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 可能不是,但我仍然迷失在直觉上,尤其是当它适用于我的表。

那么这里有什么不同呢?

【问题讨论】:

    标签: sql postgresql where-clause


    【解决方案1】:

    子查询不等价:

    第一个

    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的最大treatment
    3. outcome = 1 计算每个id 的行数。

    第二个

    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的最大值treatment
    3. 计算子集中每个id 的行数(已过滤)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 2022-11-15
      • 2018-02-18
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      相关资源
      最近更新 更多