SQL组按表中的列,如何获取count = 0的组?

时间:2014-06-11 11:01:09

标签: sql oracle count group-by

我正在编写一个shell脚本来生成记录计数报告。

样本表&数据:MED_FILE_TEST_RECORD

================================================================================
R_ID    SOURCE  ELEMENT FILE_STATUS FILE_CREATE_TIME    FILE_NAME

================================================================================
1001    Japan   ELE01   Successful      30/05/2014 15:11:23 xxxxxx1.txt
1002    Japan   ELE01   Corrupt         30/05/2014 15:11:23 xxxxxx2.txt
1003    Japan   ELE02   Successful      30/05/2014 17:11:23 xxxxxx3.txt
1004    Japan   ELE02   Successful      30/05/2014 17:11:23 xxxxxx4.txt
1005    Japan   ELE01   Corrupt         31/05/2014 15:11:23 xxxxxx5.txt

================================================================================

我使用以下Oracle SQL生成报告。计数结果正确生成。

SELECT SOURCE, ELEMENT, FILE_STATUS, FILE_CREATE_TIME as DAY, COALESCE(COUNT(FILE_CREATE_TIME), 0) as FILE_COUNT
FROM MED_FILE_TEST_RECORD
WHERE 
(SOURCE IN ('Japan')) AND 
(ELEMENT IN ( 'ELE01', 'ELE02' )) AND 
(FILE_STATUS IN ( 'Corrupt', 'Successful' ))  AND
(FILE_CREATE_TIME BETWEEN to_date('2014-05-30 00:00:00','YYYY-MM-DD HH24:MI:SS') AND to_date('2014-06-01 23:59:59','YYYY-MM-DD HH24:MI:SS'))
GROUP BY SOURCE, ELEMENT, FILE_STATUS, FILE_CREATE_TIME
ORDER BY DAY, SOURCE, ELEMENT, FILE_STATUS desc;

计数结果:

================================================================================ 
SOURCE  ELEMENT FILE_STATUS FILE_CREATE_TIME    FILE_COUNT

================================================================================
Japan   ELE01   Successful  30/05/2014  1
Japan   ELE01   Corrupt 30/05/2014  1
Japan   ELE02   Successful  30/05/2014  2
Japan   ELE01   Corrupt 31/05/2014  1
================================================================================

可以生成count = 0的结果,如下所示?那么报告读者可以清楚地知道某些群体在特定时间没有记录?谢谢!

================================================================================
SOURCE  ELEMENT FILE_STATUS FILE_CREATE_TIME    FILE_COUNT

================================================================================
Japan   ELE01   Successful  30/05/2014  1
Japan   ELE01   Corrupt 30/05/2014  1
Japan   ELE02   Successful  30/05/2014  2
Japan   ELE02   Corrupt 30/05/2014  0
Japan   ELE01   Successful  31/05/2014  0
Japan   ELE01   Corrupt 31/05/2014  1
Japan   ELE02   Successful  31/05/2014  0
Japan   ELE02   Corrupt 31/05/2014  0
Japan   ELE01   Successful  01/06/2014  0
Japan   ELE01   Corrupt 01/06/2014  0
Japan   ELE02   Successful  01/06/2014  0
Japan   ELE02   Corrupt 01/06/2014  0

2 个答案:

答案 0 :(得分:0)

要对使用聚合列(使用GROUP BY创建)创建的列执行选择,您需要HAVING clause,其工作方式与WHERE子句非常相似。尝试在查询结尾处添加以下内容:

...
HAVING FILE_COUNT = 0

答案 1 :(得分:0)

左连接可用于执行此操作。

我首先使用with语句获取我想要显示的所有记录,然后我将其与原始表连接起来。这将确保所有行都保留在其中,但对于那些没有结果的行,r.file_create_time将为NULL,因此您将知道这些行有0个结果。

with T1 as
(select distinct SOURCE, ELEMENT, FILE_STATUS, FILE_CREATE_TIME as DAY
 from MED_FILE_TEST_RECORD
)
select t1.*, COUNT(r.FILE_CREATE_TIME)
from T1
left outer join MED_FILE_TEST_RECORD r
-- To do a meaningfull join
on t1.source = r.source
and t1.element = r.element
and t1.filestatus = r.filestatus
and t1.filecreatetime = r.file_create_time
--- And now your original where clause
AND
(r.SOURCE IN ('Japan')) AND 
(r.ELEMENT IN ( 'ELE01', 'ELE02' )) AND 
(r.FILE_STATUS IN ( 'Corrupt', 'Successful' ))  AND
(r.FILE_CREATE_TIME BETWEEN to_date('2014-05-30 00:00:00','YYYY-MM-DD HH24:MI:SS') AND to_date('2014-06-01 23:59:59','YYYY-MM-DD HH24:MI:SS'))
GROUP BY t.SOURCE, t.ELEMENT, t.FILE_STATUS, t.FILE_CREATE_TIME
ORDER BY t.FILE_CREATE_TIME, t.SOURCE, t.ELEMENT, t.FILE_STATUS desc;

可能会有一些拼写错误,但这应该有用。

如果表有一个主键,则应在ON子句中使用它来连接这两个表。