我正在尝试检索一些报告数据
这是我的疑问:
SELECT sourceCode as "Source", to_char(myTimestamp, 'YYYY-MM-DD') as "Date", statusCode as "Status", count(*) as "Count"
FROM archive_table
WHERE myTimestamp BETWEEN TO_TIMESTAMP('2013-09-30','yyyy-mm-dd') AND TO_TIMESTAMP('2013-10-05','yyyy-mm-dd')
GROUP BY sourceCode, to_char(myTimestamp, 'YYYY-MM-DD'), statusCode
ORDER BY 1, 2, 3
这是输出:
Source Date Status Count
Source1 9/30/2013 C 10
Source1 10/1/2013 C 8
Source1 10/2/2013 C 24
Source1 10/2/2013 O 4
Source2 10/4/2013 C 22
Source2 10/4/2013 O 7
Source3 10/1/2013 C 2
Source4 9/30/2013 C 15
Source4 9/30/2013 O 15
Source4 10/1/2013 C 24
Source4 10/1/2013 O 12
我希望看到的是0的所有计数,例如,日期为9/30/2013的Source1在数据库中没有状态0,所以我希望它显示:
Source1 9/30/2013 O 0
另一个例子,现在是2013年9月30日的Source2,所以它应该显示:
Source2 9/30/2013 O 0
Source2 9/30/2013 C 0
我希望有一种简单的方法可以做到这一点。有关其他信息,只有4个“来源”,状态为“O”或“C”,显然日期范围在where子句中提供。
答案 0 :(得分:2)
最简单的方法是,如果您有一个包含可能的来源,状态和日期的值表。即使不这样做,您仍然可以动态生成可以支持查询的派生表。
这会生成您尝试查询的源,状态和日期的每个组合。
select
*
from
(select 'Source1' Source from Dual
union select 'Source2' from Dual
union select 'Source3' from Dual
union select 'Source4' from Dual
) s
cross join (
select 'O' Status from Dual
union select 'C' from Dual
) c
cross join (
select '2013-09-30' Dt from Dual
union select '2013-10-01' from Dual
union select '2013-10-02' from Dual
union select '2013-10-03' from Dual
union select '2013-10-04' from Dual
union select '2013-10-05' from Dual
) d;
然后你可以完成所有这些并离开join到你的archive_table,然后对你编造的数据进行分组,而不是你的基表,并对你的一个archive_table列进行计数。
select
s.Source,
c.Status,
d.Dt,
count(t.Source)
from
(select 'Source1' Source from Dual
union select 'Source2' from Dual
union select 'Source3' from Dual
union select 'Source4' from Dual
) s
cross join (
select 'O' Status from Dual
union select 'C' from Dual
) c
cross join (
select '2013-09-30' Dt from Dual
union select '2013-10-01' from Dual
union select '2013-10-02' from Dual
union select '2013-10-03' from Dual
union select '2013-10-04' from Dual
union select '2013-10-05' from Dual
) d
left join test t
on s.Source = t.Source
and c.Status = t.Status
and d.Dt = t.Dt
group by
s.Source,
c.Status,
d.Dt
答案 1 :(得分:1)
不要在日期范围内指定每个日期,而是使用以下内容,您只需要包含开始日期和结束日期:
SELECT
TO_DATE('09/30/2013','mm/dd/yyyy') - 1 + LEVEL dt
FROM dual
CONNECT BY
LEVEL <= ( TO_DATE('10/05/2013','mm/dd/yyyy')
- TO_DATE('09/30/2013','mm/dd/yyyy')) + 1