如何单独显示和识别每月的所有日子(例如星期一,星期二)?

时间:2014-04-23 08:19:40

标签: sql oracle dayofweek

请帮帮我。我坚持了好几个小时。我想每个月单独显示所有日子(例如星期一,星期二),并显示每天的相应日期。

我该怎么做?我真的需要帮助。谢谢

期望的输出:

Data,Date,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
Data,04/01/2014,10,12,5,6,1,0,15
Data,04/07/2014,14,1,5,6,1,2,18
Data,04/14/2014,11,12,5,6,1,0,17

这是SQL脚本:

select 'Data'
||','||to_char(d.dtime_day, 'MM/dd/yyyy')
||','||nvl(m.mtotal, 0)
||','||nvl(tu.tutotal, 0)
||','||nvl(w.wtotal, 0)
||','||nvl(th.thtotal, 0)
||','||nvl(f.ftotal, 0)
||','||nvl(s.stotal, 0)
||','||nvl(su.sutotal, 0)
from table0.dc_date d
left join (
        select trunc(t.create_time) as monday
              ,count(t.create_time) as mtotal
        from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'
        group by trunc(t.create_time)
) m on d.dtime_day = m.monday
left join (
        select trunc(t.create_time, 'DD') as tuesday
              ,count(t.create_time) as tutotal
        from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'

        group by trunc(t.create_time, 'DD')
) tu on d.dtime_day = tu.tuesday
left join (
        select trunc(t.create_time, 'DD') as wednesday
              ,count(t.create_time) as wtotal
         from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'
        group by trunc(t.create_time, 'DD')
) w on d.dtime_day = w.wednesday
left join (
        select trunc(t.create_time, 'DD') as thursday
              ,count(t.create_time) as thtotal
         from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'
        group by trunc(t.create_time, 'DD')
) th on d.dtime_day = th.thursday
left join (
        select trunc(t.create_time, 'DD') as friday
              ,count(t.create_time) as ftotal
        from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'
        group by trunc(t.create_time, 'DD')
) f on d.dtime_day = f.friday
left join (
        select trunc(t.create_time, 'DD') as saturday
              ,count(t.create_time) as stotal
        from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'
        group by trunc(t.create_time, 'DD')
) s on d.dtime_day = s.saturday
left join (
        select trunc(t.create_time, 'DD') as sunday
              ,count(t.create_time) as sutotal
        from table.table1 t
        left join table.table2 q
        on q.id = t.queue_id
        where t.create_time between trunc(sysdate,'DD')-12*7 and sysdate -1
        and q.name not like 'item0%'
        or q.name not like 'item%'
        group by trunc(t.create_time, 'DD')
) su on d.dtime_DAY = su.sunday
where d.dtime_day between trunc(sysdate,'DD')-12*7 and trunc(sysdate) -1
and trunc(d.dtime_day, 'DD')= d.dtime_day
order by d.dtime_day

enter image description here

我想在每天都显示日期

1 个答案:

答案 0 :(得分:1)

所有左连接子查询似乎都在做同样的事情,而你实际上并没有限制一周中的任何事情。您只需要加入一次,然后您需要转动该连接的结果。如果您使用的是11g,则可以使用真正的支点:

select 'Data'
  ||','|| to_char(week_start, 'MM/dd/yyyy')
  ||','|| mon_cnt
  ||','|| tue_cnt
  ||','|| wed_cnt
  ||','|| thu_cnt
  ||','|| fri_cnt
  ||','|| sat_cnt
  ||','|| sun_cnt
from (
  select 'Data',
    next_day(d.dtime_day - 7, 'Monday') as week_start,
    to_char(d.dtime_day, 'Dy') as day_of_week,
    t.create_time
  from dc_date d
  left join table1 t
  on t.create_time >= d.dtime_day
  and t.create_time < d.dtime_day + 1
  left join table2 q
  on q.id = t.queue_id
  and (q.name not like 'item0%' or q.name not like 'item%')
  where d.dtime_day between trunc(sysdate) - (12*7) and trunc(sysdate) -1
)
pivot (count(create_time) as cnt for (day_of_week)
  in ('Mon' as mon, 'Tue' as tue, 'Wed' as wed, 'Thu' as thu,
    'Fri' as fri, 'Sat' as sat, 'Sun' as sun))
order by week_start;

如果你不是11g,你可以用老式的方式做到:

select 'Data'
  ||','|| to_char(next_day(d.dtime_day - 7, 'Monday'), 'MM/dd/yyyy')
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Mon'
    then t.create_time end)
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Tue'
    then t.create_time end)
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Web'
    then t.create_time end)
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Thu'
    then t.create_time end)
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Fri'
    then t.create_time end)
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Sat'
    then t.create_time end)
  ||','|| count(case when to_char(d.dtime_day, 'Dy') = 'Sun'
    then t.create_time end)
from dc_date d
left join table1 t
on t.create_time >= d.dtime_day
and t.create_time < d.dtime_day + 1
left join table2 q
on q.id = t.queue_id
and (q.name not like 'item0%' or q.name not like 'item%')
where d.dtime_day between trunc(sysdate) - (12*7) and trunc(sysdate) -1
group by next_day(d.dtime_day - 7, 'Monday')
order by next_day(d.dtime_day - 7, 'Monday');

日期名称对NLS敏感,因此to_char调用应该具有可选的第三个参数来强制执行该语言;但我已经使用next_day进行分组并且依赖于会话设置,所以你的会话必须是英文 - 或者至少,所有用于日期名称的值都必须与你的会话一致语言。如果这可以由任何人运行,那将是一个问题,但如果这是一个生成报告的脚本,那么您可以将脚本中的语言设置为变通方法。

您还没有提供表格结构或数据,所以我做了一些。有了这个:

create table dc_date (dtime_day date);
insert into dc_date
select date '2014-03-28' + level
from dual
connect by level < 30;

create table table1 (create_time date, queue_id number);
insert into table1 values (sysdate - 1, 1);
insert into table1 values (sysdate - 0.75, 1);
insert into table1 values (sysdate - 5, 1);
insert into table1 values (sysdate - 10, 1);
insert into table1 values (sysdate - 15, 1);

create table table2 (id number, name varchar2(10));
insert into table2 values (1, 'anything');

......两个查询都得到:

Data,03/24/2014,0,0,0,0,0,0,0
Data,03/31/2014,0,0,0,0,0,0,0
Data,04/07/2014,0,1,0,0,0,0,1
Data,04/14/2014,0,0,0,0,1,0,0
Data,04/21/2014,0,2,0,0,0,0,0

我昨天创建了两个记录,因此{星期二'列中的2出现在4月21日开始的星期(星期一)。我认为这就是你想要的。