【问题标题】:Conditional count of rows where at least one peer qualifies至少一个对等点符合条件的行数
【发布时间】:2025-11-26 05:35:01
【问题描述】:

背景

我是 SQL 新手。在Windows 10本地使用PostgreSQL 13,我有一张表t

+--+---------+-------+
|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    |
+-----------------------+-----+

首先,确定曾经被处理过的id。被“对待”意味着与treatment = 1 有任何一行。

其次,用outcome = 1 为这两组中的每一个计算行数。从我的原始表格中,“曾经治疗”的ids 总共有 3 个outcome = 1,可以说,“从未治疗”有 1 `结果 = 1。

我的尝试

我想,通过这样的方式,我可以走得更远:

select treatment, count(outcome)
from t
group by treatment;

但这只会让我得到这个结果:

+---------+-----+
|treatment|count|
+---------+-----+
|0        |2    |
|1        |4    |
+---------+-----+

【问题讨论】:

  • 嘿@ErwinBrandstetter,对不起,被从电脑上拉走了。在主帖中查看我的编辑。我试图澄清我想要的东西。 (虽然还没有尝试过你的答案,我现在就这样做。)我真的要求做两件事,我现在意识到:通过我解释的“曾经处理过”的标准来识别不同的 id,以及然后将outcome=1 相加。

标签: sql postgresql aggregate-filter


【解决方案1】:

对于更新的问题:

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;
 ever_treated | count 
--------------+-------
            0 |     1
            1 |     3

db小提琴here

阅读:

  • 对于那些根本没有得到治疗的人(所有treatment = 0),我们看到1 x outcome = 1
  • 对于那些接受过任何治疗的人(至少一个treatment = 1),我们看到3 x outcome = 1

使用正确的boolean 值而不是integer 会更简单、更快。

【讨论】:

  • 太棒了,非常感谢。很抱歉第一次搞混了! 编辑:作为一个新手,我可以问一下,什么会使boolean 更简单? (我明白为什么它会更快。)
【解决方案2】:

(更新问题的答案)

这是一个易于理解的子查询逻辑,适用于整数:

    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;

【讨论】:

  • 嘿@Heidiki,我刚刚尝试了您的解决方案,并且意识到我没有很好地表达我的问题。看看我刚刚制作的edit,看看这是否会改变您对事物的理解。我很抱歉。
  • 感谢您的更新,它运行良好,并且比其他解决方案更易于阅读!
最近更新 更多