postgresql select 列两次,条件不同

postgresql select column twice with different creteria

使用 PostgreSQL:我有一个 table 名为“people”的 4 列: id、user_id、date_id 和状态(可以有两个值:“已显示”、“注册”)

我希望通过 select 查询显示 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

基本上,我尝试 select 一列 (people_attending),其中 p.status =“已显示”,然后是第三列 (people_registered),其中 p.status = 所有情况。我的前两列对上面的查询没问题,但是,第三列有问题。

我很难找到解决方案,正在阅读 并尝试进行自连接。

感谢您的帮助, MM.

根据 PostgreSQL documentation:

count ( "any" ) → bigint

Computes the number of input rows in which the input value is not null.

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

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

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

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)

话虽如此,我会考虑(如果可能的话)将原始数据导入您的应用程序并在那里进行计算。五年后当你回来对你的项目做一些错误时,它会更容易理解fixing/addition。