【问题标题】:SQL group by columns in a table, how to get group with count = 0?SQL按表中的列分组,如何获得count = 0的组?
【发布时间】:2014-08-01 09:52:58
【问题描述】:

我正在编写一个 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

【问题讨论】:

  • 你尝试过使用Having子句吗?

标签: sql oracle count group-by


【解决方案1】:

可以使用左连接来做到这一点。

我首先使用 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 子句中使用它来连接两个表。

【讨论】:

  • 感谢您的建议!我可以通过(1st)通过交叉连接组合整个行和列来实现我想要的结果。 (2)左加入我的查询,这将得到真实的数据。
【解决方案2】:

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

...
HAVING FILE_COUNT = 0

【讨论】:

    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    相关资源
    最近更新 更多