我有一个具有以下结构的表。
Note_title varchar2(100)
Note_created_on date
现在在报告中,我想显示每周创建的所有笔记,因此我为它实施了以下解决方案。
SELECT to_char(Note_created_on - 7/24,'ww')||'/'||to_char(Note_created_on - 7/24,'yyyy') as Week ,
nvl(COUNT(Note_title),'0') as AMOUNT
FROM Notes
GROUP BY to_char(Note_created_on - 7/24,'ww') ,
to_char(Note_created_on -7/24,'yyyy')
ORDER BY to_char(Note_created_on - 7/24,'ww') DESC
我从中得到正确的输出,但是假设第42,45周没有创建任何注释,那么它只是缺少它。 样本输出:
WEEK AMOUNT
46/2018 3
44/2018 22
43/2018 45
41/2018 1
40/2018 2
39/2018 27
38/2018 23
那么我如何在第42,45周获得零值而不是将它们排除在外?
答案 0 :(得分:0)
正如jarlh所述:
创建星期列表:
SELECT TO_CHAR(LEVEL, 'FM00')||'/2018' wk
FROM dual
CONNECT BY LEVEL <= 53
此查询生成53行,级别仅是一个数字.... 2 ..最多53。我们将其格式化为01/2018,02/2018 .. 53/2018
如果您打算在其他年份使用此查询,最好将年份设置为动态:
SELECT TO_CHAR(LEVEL, 'FM00')||TO_CHAR(sysdate-7/24,'/YYYY') wk
FROM dual
CONNECT BY LEVEL <= 53
(感谢Barbaros指出,Oracle将任何一年的最后一天报告为在第53周,或者说是7 * 52 = 364)
我们将注释数据加入其中。我不清楚您为什么要从日期中减去7个小时(时区?),但我还是留下了。我消除了计数的复杂性,因为您似乎只想要特定一周中的记录计数。我还删除了双精度to_char,因为您可以在单个操作中完成所有操作。不需要TO_CHAR(date, 'WW')||'/'||TO_CHAR(date,'YYYY')
等。您只需使用WW/YYYY
作为格式即可。现在,我们的查询如下:
SELECT lst.wk as week, COALESCE(amt, 0) as amount FROM
(
SELECT TO_CHAR(LEVEL, 'FM00')||TO_CHAR(sysdate-7/24,'/YYYY') wk
FROM dual
CONNECT BY LEVEL <= 52
) lst
LEFT OUTER JOIN
(
SELECT
to_char(Note_created_on - 7/24,'ww/yyyy') as wk,
COUNT(*) as amt
FROM Notes
GROUP BY to_char(Note_created_on - 7/24,'ww/yyyy')
) dat
ON lst.wk = dat.wk
ORDER BY lst.wk
在没有音符的星期中,左连接在该星期中记录为空,因此我们将其合并为0。
您当然可以用其他方式(许多方式)进行查询,这是一个比较:
SELECT lst.wk as week, COUNT(dat.wk) as amount FROM
(
SELECT TO_CHAR(LEVEL, 'FM00')||TO_CHAR(sysdate-7/24,'/YYYY') wk
FROM dual
CONNECT BY LEVEL <= 52
) lst
LEFT OUTER JOIN
(
SELECT
to_char(Note_created_on - 7/24,'ww/yyyy') as wk
FROM Notes
) dat
ON lst.wk = dat.wk
GROUP BY lst.wk
ORDER BY lst.wk
在这种形式下,我们在加入后进行groupby / count。通过计算dat.wk(对于某些lst.wk可能为NULL),我们可以省略合并,因为count(null)为0
答案 1 :(得分:0)
首先,您需要生成每年之间的所有星期,之后再与“ Notes”表上的“周”合并,然后按“生成的周”分组。例如:
with weeks
as ( select level as lvl /*Assume 52 weeks in a calendar year..*/
from dual
connect by level <=52
)
,weeks_year
as (select distinct
b.lvl||'/'||trunc(Note_created_on,'YYYY') as week_year_val /*From the start of year in Note_created_on*/
from Notes a
join weeks b
on 1=1
)
SELECT a.week_year_val as Week
,COUNT(Note_title) as AMOUNT
FROM weeks_year a
LEFT JOIN Notes b
ON a.week_year_val=to_char(b.Note_created_on - 7/24,'ww')||'/'||to_char(b.Note_created_on - 7/24,'yyyy')
GROUP BY a.week_year_val
ORDER BY a.week_year_val DESC
答案 2 :(得分:0)
如果要在当前年份的 中执行此操作,则可以使用以下 SQL语句,该语句使用如下的RIGHT JOIN
:
SELECT d.week as Week,
nvl(COUNT(Note_title), '0') as AMOUNT
FROM Notes
RIGHT JOIN
(SELECT lpad(level,2,'0')|| '/' ||to_char(sysdate,'yyyy') as week,
'0' as amount FROM dual CONNECT BY level <= 53) d
ON
( d.week =
to_char(Note_created_on - 7 / 24, 'ww') ||'/'||to_char(Note_created_on - 7 / 24, 'yyyy') )
GROUP BY d.week
ORDER BY d.week DESC;
P.S。人们普遍认为,一年由52
个周组成,是正确的但被截断了:)。因此,我使用了53
,
请注意,select to_char( date'2016-12-31' - 7 / 24, 'ww') from dual
将产生53
作为样本。