【问题标题】:postgresql select column twice with different creteriapostgresql用不同的标准选择列两次
【发布时间】:2021-04-20 13:22:16
【问题描述】:

使用 PostgreSQL:我有一个名为“people”的表,有 4 列: id、user_id、date_id 和 status(可以有两个值:“showed”“signup”)

我希望通过选择查询显示 3 列:

SELECT date_id, count(DISTINCT p.user_id) as people_attending, count(p.id) as people_registered
FROM people p
where (p.status::TEXT = 'showed') + MISSING PART HERE??
GROUP BY date_id
ORDER BY "date_id" ASC

希望得到这个:

date_id || people_attending || people_registered 
12      || 100              || 230
34      || 10               || 12

基本上,我试图选择一列 (people_attending),其中 p.status = "showed",然后选择第三列 (people_registered),其中 p.status = 所有案例。我的前两列对上面的查询很好,但是,第三列是个问题。

我很难找到解决方案,阅读 Selecting same column twice from a single table but with different conditions 并尝试进行自我加入。

感谢您的帮助, 嗯。

【问题讨论】:

    标签: postgresql inner-join


    【解决方案1】:

    根据 PostgreSQL documentation:

    count ("any") → bigint

    计算输入值不为空的输入行数。

    所以你可以在一个条件下计算人数:

    SELECT 
      date_id, 
      count(DISTINCT CASE WHEN status = 'showed' THEN p.user_id ELSE NULL END) as people_attending,
      count(DISTINCT CASE WHEN status = 'signup' THEN p.user_id ELSE NULL END) as people_registered
    FROM 
      people p
    GROUP BY 
      date_id
    ORDER BY
      "date_id" ASC
    

    您可以使用更紧凑的 FILTER 形式(请参阅aggregate expresions

    SELECT 
      date_id, 
      count(DISTINCT p.user_id) FILTER (WHERE status = 'showed') as people_attending,
      count(DISTINCT p.user_id) FILTER (WHERE status = 'signup') as people_registered
    FROM 
      people p
    GROUP BY 
      date_id
    ORDER BY
      "date_id" ASC
    

    【讨论】:

    • 谢谢!我用了你的第二个版本,这个过滤器真的很有用。
    【解决方案2】:

    如果您必须使用一个查询来获得完全相同的结果集,您可以尝试以下查询:

    select a00.date_id, a01.c as showed, a00.c as all_participants
      from
       (
           select date_id, 'all', count(1) as c from people group by date_id
       ) a00 left outer join
       (
           select date_id, 'showed', count(1) as c from people where status = 'showed' group by date_id
       ) a01 on (a00.date_id = a01.date_id)
    

    话虽如此,我会考虑(如果可能的话)只是将原始数据输入您的应用程序并在那里进行计算。五年后,当您回来对项目进行某种错误修复/添加时,会更容易理解。

    【讨论】:

    • 谢谢!是的,也谢谢你的建议,真的很有用:)
    猜你喜欢
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多