如何在没有数据的情况下依然显示该行数据?

[复制链接]
查看11 | 回复9 | 2009-10-14 18:49:45 | 显示全部楼层 |阅读模式
下图是报表的部分表样

重点是中间那个日期的部分,需求是这样的,客户选择一个月粒度的日期,然后统计显示当月的第一个周6以及其后3天的数据,就是如图上的周六,周日,周一,周二的数据。测试用的脚本和我自己写的SQL语句贴在下面,稍微解释一下,客户在前台选择一个月粒度的日期后,传到后台的是当月第一天的日期,就是下面脚本里的‘2010-2-1’
现在的问题是,客户要求,就算没有那一天的数据,也要按照要求格式显示出那4天的日期。。也是图上的下半部分的样子。。也就是说,哪怕没有周日的数据,也必须有周日那一行,只不过后面为空就是了。。。请问应该怎么做??
顺便如果SQL语句写的不好也请不吝指教

create table tt_time(t date);
insert into tt_time values('1-2月-2010');
insert into tt_time values('6-2月-2010');
insert into tt_time values('7-2月-2010');
insert into tt_time values('8-2月-2010');
insert into tt_time values('9-2月-2010');
insert into tt_time values('10-2月-2010');

SELECT decode(to_char(t,'d'),
7,to_char(t,'mm')||'月'||to_char(t,'dd')||'日'||'(周六)',
1,to_char(t,'mm')||'月'||to_char(t,'dd')||'日'||'(周日)',
2,to_char(t,'mm')||'月'||to_char(t,'dd')||'日'||'(周一)',
3,to_char(t,'mm')||'月'||to_char(t,'dd')||'日'||'(周二)',
null)
FROM tt_time
WHERE t BETWEEN
decode(to_char(to_date('2010-2-1','yyyy-mm-dd'),'d'),1,to_date('2010-2-1','yyyy-mm-dd') + 6 , to_date('2010-2-1','yyyy-mm-dd') + (7 - to_char(to_date('2010-2-1','yyyy-mm-dd'),'d')))
AND
(decode(to_char(to_date('2010-2-1','yyyy-mm-dd'),'d'),1,to_date('2010-2-1','yyyy-mm-dd') + 6 , to_date('2010-2-1','yyyy-mm-dd') + (7 - to_char(to_date('2010-2-1','yyyy-mm-dd'),'d'))) + 3)
ORDER BY decode(to_char(t,'d'),7,1,1,2,2,3,3,4)
[ 本帖最后由 风铃中の鬼 于 2010-2-9 17:46 编辑 ]
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
应该这样做,用户随便选择一个日期,然后自己构造第1个周六和后面3个日期,然后和相关数据源表外联接,这样就行了,自己构造下日期就可以,不要用源表的日期
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
没有看到图片,比如外面传了个日期进去2010-3-6日,那么是招3月份第1个周六以及之后的周日周一周二,假设个数据表
create table datas
(
tt_time date,
num number
);
insert into datas values('7-3月-2010',10);
insert into datas values('8-3月-2010',10);
只有两条数据
下面构造日期数据集,关联datas表查询
select
to_char(time_table.tt_time,'yyyy-mm-dd (Dy)'),datas.num
from
datas,
(with temp
as(
selectdecode(to_char(trunc(to_date('2010-3-6','yyyy-mm-dd'),'mm'),'DY'),'星期六',to_date('2010-3-6','yyyy-mm-dd'),
next_day(trunc(to_date('2010-3-6','yyyy-mm-dd'),'mm'),'星期六')) selected_date from dual
)
select selected_datett_time from temp
union all
select selected_date+1 from temp
union all
select selected_date+2 from temp
union all
selectselected_date+3 from temp
) time_table
where datas.tt_time(+)=time_table.tt_time order by time_table.tt_time;
--result
TO_CHAR(TIME_TABLE.TT_TIME,'YYNUM
------------------------------ ----------
2010-03-06 (星期六)
2010-03-07 (星期日) 10
2010-03-08 (星期一) 10
2010-03-09 (星期二)
里面的参数根据数据库格式可能有差别,另外你可能直接把当月第1天传进去了,也可以修改下日期构造
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
抱歉工作原因回复的晚了点。。
因为需求实际是用在DB2上的。。。所以改成DB2的版本做了下试验。。DB2也支持with写法,但是不支持把with写在from后面。所以改了改。。换成oracle版本的写法如下,只是吧with移到上面去了而已:
create table tt_time(t date,d integer);
insert into tt_time values('1-2月-2010',10);
insert into tt_time values('6-2月-2010',10);
insert into tt_time values('7-2月-2010');
insert into tt_time values('8-2月-2010',10);
insert into tt_time values('9-2月-2010');
insert into tt_time values('10-2月-2010');

with tt
as
(SELECT
decode(to_char(to_date('2010-2-1','yyyy-mm-dd'),'DY'),'星期六',to_date('2010-2-1','yyyy-mm-dd'),
next_day(to_date('2010-2-1','yyyy-mm-dd'),'星期六')) t_2
from dual
union all
SELECT
decode(to_char(to_date('2010-2-1','yyyy-mm-dd'),'DY'),'星期六',to_date('2010-2-1','yyyy-mm-dd'),
next_day(to_date('2010-2-1','yyyy-mm-dd'),'星期六')) + 1
from dual
union all
SELECT
decode(to_char(to_date('2010-2-1','yyyy-mm-dd'),'DY'),'星期六',to_date('2010-2-1','yyyy-mm-dd'),
next_day(to_date('2010-2-1','yyyy-mm-dd'),'星期六')) + 2
from dual
union all
SELECT
decode(to_char(to_date('2010-2-1','yyyy-mm-dd'),'DY'),'星期六',to_date('2010-2-1','yyyy-mm-dd'),
next_day(to_date('2010-2-1','yyyy-mm-dd'),'星期六')) + 3
from dual)
select decode(to_char(tt.t_2,'d'),
7,to_char(tt.t_2,'mm')||'月'||to_char(tt.t_2,'dd')||'日'||'(周六)',
1,to_char(tt.t_2,'mm')||'月'||to_char(tt.t_2,'dd')||'日'||'(周日)',
2,to_char(tt.t_2,'mm')||'月'||to_char(tt.t_2,'dd')||'日'||'(周一)',
3,to_char(tt.t_2,'mm')||'月'||to_char(tt.t_2,'dd')||'日'||'(周二)',
null),
tt_time.d
from tt,tt_time
where tt.t_2 = tt_time.t(+)
order by tt.t_2


DB2版写法如下:

with tt(t_2)
as
(
select decode(DAYOFWEEK_ISO('2010-2-1'),7,date('2010-2-1') + 6 day,date('2010-2-1') + (6 - DAYOFWEEK_ISO('2010-2-1')) day)
from SYSIBM.SYSDUMMY1
UNION ALL
select decode(DAYOFWEEK_ISO('2010-2-1'),7,date('2010-2-1') + 6 day,date('2010-2-1') + (6 - DAYOFWEEK_ISO('2010-2-1')) day) + 1 day
from SYSIBM.SYSDUMMY1
UNION ALL
select decode(DAYOFWEEK_ISO('2010-2-1'),7,date('2010-2-1') + 6 day,date('2010-2-1') + (6 - DAYOFWEEK_ISO('2010-2-1')) day) + 2 day
from SYSIBM.SYSDUMMY1
UNION ALL
select decode(DAYOFWEEK_ISO('2010-2-1'),7,date('2010-2-1') + 6 day,date('2010-2-1') + (6 - DAYOFWEEK_ISO('2010-2-1')) day) + 3 day
from SYSIBM.SYSDUMMY1
)
select

decode(DAYOFWEEK_ISO(tt.t_2),6,month(tt.t_2)||'月'||day(tt.t_2)||'日'||'(周六)',7,month(tt.t_2)||'月'||day(tt.t_2)||'日'||'(周日)',1,month(tt.t_2)||'月'||day(tt.t_2)||'日'||'(周一)',2,month(tt.t_2)||'月'||day(tt.t_2)||'日'||'(周二)',null),

tt_time.d
from tt left outer join tt_time on tt.t_2 = tt_time.t
order by tt.t_2
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
因为传入的是当月第一天,所以不用trunc()
问题解决,非常感谢
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
请把图片作为附件
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
原帖由 〇〇 于 2010-2-9 17:25 发表
请把图片作为附件

我上午还在郁闷图片的显示方法怎么不对呢。。。。一经提醒,想起来了。。。
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
明白了
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
又把这个问题顶上来了。。今天把这个SQL改到报表中又发现了新问题。急需各位再指点。。。。
如一楼那个图,用外连接的话日期的确是现实齐全了,但是网元那里是空。。没有办法像上面那个图一样出来详见下面附件图。。另外客户的要求是,所有网元都要显示出来,哪怕网元没数据,就像那时间一样。。。比如有网通但网通没有数据,也要照上面的格式显示出来。。。具体的效果如下:
网元 日期
数据
------------------------------------------------------------------------
电信02月07日(周六)
电信02月07日(周日)10
电信02月07日(周一)10
电信02月07日(周二)
网通02月07日(周六)10
网通02月07日(周日)
网通02月07日(周一)10
网通02月07日(周二)
联通02月07日(周六)10
联通02月07日(周日)
联通02月07日(周一)10
联通02月07日(周二)10
铁通02月07日(周六)
铁通02月07日(周日)
铁通02月07日(周一)
铁通02月07日(周二)

脚本:
create table tt_time(ne_id integer,t date,d integer);
insert into tt_time values(1,'1-2月-2010',10);
insert into tt_time values(1,'6-2月-2010',10);
insert into tt_time values(1,'8-2月-2010',10);
insert into tt_time values(2,'1-2月-2010',10);
insert into tt_time values(2,'7-2月-2010',10);
insert into tt_time values(2,'8-2月-2010',10);
insert into tt_time values(3,'9-2月-2010',10);
insert into tt_time values(3,'6-2月-2010',10);
insert into tt_time values(3,'8-2月-2010',10);

create table tt_ne(ne_name varchar2(20),ne_id integer);
insert into tt_ne values('网通',1);
insert into tt_ne values('电信',2);
insert into tt_ne values('联通',3);
insert into tt_ne values('铁通',4);
回复

使用道具 举报

千问 | 2009-10-14 18:49:45 | 显示全部楼层
原帖由 风铃中の鬼 于 2010-2-9 15:47 发表
抱歉工作原因回复的晚了点。。
因为需求实际是用在DB2上的。。。

打住~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行