简体   繁体   English

如何在group by子句中支持两个条件(PostgreSQL)

[英]How to support two conditions in the group by clause (postgresql)

I have three table TableA, TableB, TableC they all are linked by id. 我有三个表TableA,TableB,TableC,它们都由ID链接。 Table A has logTime and tableB has detectionTime and TableC has emptId. 表A具有logTime,表B具有detectionTime,而表C具有emptId。

For each empId I want 1. count of logTime when no detectionTime found in tableB 2. average of logTime and detectionTime difference if detectionTime found. 我想要的每个empId 1.在tableB中未找到detectionTime时的logTime计数2.如果找到detectionTime,则logTime和detectionTime差的平均值。

I have written this query that gets the average when detectionTime found but not sure how to get data when detectionTime not found 我已经编写了此查询,该查询在发现detectionTime时获取平均值,但是不确定在detectionTime未找到时如何获取数据

select det.empid  ,average(det.blocked_time) 
FROM (SELECT c.emplid as empid, EXTRACT(EPOCH FROM ( a.detectionTime - b.logTime )) as blocked_time
        ## inner and join condition here
  ) As det group by det.emplid where dat.blocked_time>0

Here I got entry when blocked_time>0 average and other stats. 当blocked_time> 0平均和其他统计信息时,我在这里输入了数据。

How to get count of blocked_time for each empId when blocked_time is 0 当blocked_time为0时,如何获取每个empId的blocked_time计数

First, a few comments: 首先,一些评论:

  • Your. 你的。 SQL statement is syntactically incorrect. SQL语句在语法上不正确。 WHERE must come before GROUP BY . WHERE必须出现在GROUP BY

  • Your query seems to assume that id is a unique key for all three tables. 您的查询似乎假设id是所有三个表的唯一键。 Otherwise the same value could appear in the join result multiple times. 否则,相同的值可能会多次出现在联接结果中。

The expression you are looking for is 您要寻找的表情是

count(blocked_time) FILTER (WHERE blocked_time = 0)

As no sample data is shared, so an (assumed) option could be to use left join and coalesce in inner query to convert NULL values for detectionTime to 0 and then use conditional aggregation in outer query as below. 由于没有共享任何样本数据,因此(假定的)选项可能是在内部查询中使用left joincoalesce ,将detectionTime NULL值转换为0 ,然后在外部查询中使用条件聚合,如下所示。

select det.empid  ,
       avg(case when detectionTime  > 0 then det.blocked_time end) as avgBlockedTime, 
       sum(case when detectionTime =  0 then 0 else 1 end) as logTimeCount
FROM (SELECT c.emplid as empid, 
      EXTRACT(EPOCH FROM ( a.detectionTime - b.logTime )) as blocked_time,
      coalesce(DetectionTime,0) as detectionTime
      ## left outer join and condition here
  ) As det 
group by det.empid

Try this out: 试试看:

select emptid,
sum(case when detectiontime is null then 1 else 0 end) as count,
average(case when detectiontime is not null then diff else 0 end) as avg
(
select a.*,b.detectiontime,c.emptid,a.logtime-b.detectiontime as diff
from
tablea a
left join
tableb b
on a.id = b.id
left join
tablec c
on a.id = c.id
)
group by emptid;

Let me know if you are looking for something else. 让我知道您是否正在寻找其他东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM