最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。
求一SQL语句。
http://bbs.csdn.net/topics/390496661
-
create
table #tab
-
(
-
col1
char(
10),
-
col2
char(
10),
-
item
char(
10),
-
num
int,
-
[
Date]
varchar(
10))
-
insert #tab
values(
'AAA',
'BBB',
'A',
50,
'2013-06-10')
-
insert #tab
values(
'ABB',
'BGG',
'B',
30,
'2013-06-10')
-
insert #tab
values(
'AAA',
'BBB',
'C',
80,
'2013-06-13')
我的解法:
-
create
table tab
-
(
-
col1
char(
10),
-
col2
char(
10),
-
item
char(
10),
-
num
int,
-
[
Date]
varchar(
10)
-
)
-
-
insert tab
values(
'AAA',
'BBB',
'A',
50,
'2013-06-10')
-
insert tab
values(
'ABB',
'BGG',
'B',
30,
'2013-06-10')
-
insert tab
values(
'AAA',
'BBB',
'C',
80,
'2013-06-13')
-
-
-
-
-
--动态生成sql语句
-
declare @start_date
varchar(
10) =
'2013-06-01',
-
@end_date
varchar(
10) =
'2013-06-30';
-
-
declare @
date
varchar(
10),
-
@
sql
varchar(
max) =
'',
-
@sql1
varchar(
8000),
-
@sql2
varchar(
8000);
-
-
set @
date = @start_date;
-
-
set @sql1 =
'select case when rownum = 1 then col1 else '''' end as col1,
-
case when rownum = 1 then col2 else '''' end as col2,
-
item'
-
-
set @sql2 =
'select col1,col2,item,row_number() over(partition by col1,col2
-
order by item) as rownum'
-
-
-
while @
date <= @end_date
-
begin
-
set @sql1 = @sql1 +
',v_' +
REPLACE(
right(@
date,
5),
'-',
'') +
-
' as ''' +
CAST(
DATEPART(
month,@
date)
as
varchar) +
'/' +
-
CAST(
DATEPART(
day,@
date)
as
varchar) +
'''';
-
set @sql2 = @sql2 +
',SUM(case when date =''' + @
date +
-
''' then num else 0 end) as v_' +
-
REPLACE(
right(@
date,
5),
'-',
'')
-
-
set @
date =
CONVERT(
varchar(
10),
dateadd(
day,
1,@
date),
120)
-
end
-
-
-
set @
sql = @sql1 +
' from (' +
-
@sql2 +
' from tab
-
group by col1,col2,item' +
-
') v'
-
-
--生产的动态sql语句
-
select @
sql
-
-
-
exec(@
sql)
上面由于是动态生成语句,所以不能用局部的临时表,所以建了一个表。
下面是动态生成的sql语句,经过了格式化:
-
select
case
when
rownum =
1
then col1
else
''
end
as col1,
-
case
when
rownum =
1
then col2
else
''
end
as col2,
-
item,
-
-
v_0601
as
'6/1',v_0602
as
'6/2',v_0603
as
'6/3',
-
v_0604
as
'6/4',v_0605
as
'6/5',
-
v_0606
as
'6/6',v_0607
as
'6/7',
-
v_0608
as
'6/8',v_0609
as
'6/9',
-
v_0610
as
'6/10',v_0611
as
'6/11',
-
v_0612
as
'6/12',v_0613
as
'6/13',
-
v_0614
as
'6/14',v_0615
as
'6/15',
-
v_0616
as
'6/16',v_0617
as
'6/17',
-
v_0618
as
'6/18',v_0619
as
'6/19',
-
v_0620
as
'6/20',v_0621
as
'6/21',
-
v_0622
as
'6/22',v_0623
as
'6/23',
-
v_0624
as
'6/24',v_0625
as
'6/25',
-
v_0626
as
'6/26',v_0627
as
'6/27',
-
v_0628
as
'6/28',v_0629
as
'6/29',
-
v_0630
as
'6/30'
-
from
-
(
-
select col1,col2,item,
-
-
row_number()
over(
partition
by col1,col2
order
by item)
as
rownum,
-
-
SUM(
case
when
date =
'2013-06-01'
then
num
else
0
end)
as v_0601,
-
SUM(
case
when
date =
'2013-06-02'
then
num
else
0
end)
as v_0602,
-
SUM(
case
when
date =
'2013-06-03'
then
num
else
0
end)
as v_0603,
-
SUM(
case
when
date =
'2013-06-04'
then
num
else
0
end)
as v_0604,
-
SUM(
case
when
date =
'2013-06-05'
then
num
else
0
end)
as v_0605,
-
SUM(
case
when
date =
'2013-06-06'
then
num
else
0
end)
as v_0606,
-
SUM(
case
when
date =
'2013-06-07'
then
num
else
0
end)
as v_0607,
-
SUM(
case
when
date =
'2013-06-08'
then
num
else
0
end)
as v_0608,
-
SUM(
case
when
date =
'2013-06-09'
then
num
else
0
end)
as v_0609,
-
SUM(
case
when
date =
'2013-06-10'
then
num
else
0
end)
as v_0610,
-
SUM(
case
when
date =
'2013-06-11'
then
num
else
0
end)
as v_0611,
-
SUM(
case
when
date =
'2013-06-12'
then
num
else
0
end)
as v_0612,
-
SUM(
case
when
date =
'2013-06-13'
then
num
else
0
end)
as v_0613,
-
SUM(
case
when
date =
'2013-06-14'
then
num
else
0
end)
as v_0614,
-
SUM(
case
when
date =
'2013-06-15'
then
num
else
0
end)
as v_0615,
-
SUM(
case
when
date =
'2013-06-16'
then
num
else
0
end)
as v_0616,
-
SUM(
case
when
date =
'2013-06-17'
then
num
else
0
end)
as v_0617,
-
SUM(
case
when
date =
'2013-06-18'
then
num
else
0
end)
as v_0618,
-
SUM(
case
when
date =
'2013-06-19'
then
num
else
0
end)
as v_0619,
-
SUM(
case
when
date =
'2013-06-20'
then
num
else
0
end)
as v_0620,
-
SUM(
case
when
date =
'2013-06-21'
then
num
else
0
end)
as v_0621,
-
SUM(
case
when
date =
'2013-06-22'
then
num
else
0
end)
as v_0622,
-
SUM(
case
when
date =
'2013-06-23'
then
num
else
0
end)
as v_0623,
-
SUM(
case
when
date =
'2013-06-24'
then
num
else
0
end)
as v_0624,
-
SUM(
case
when
date =
'2013-06-25'
then
num
else
0
end)
as v_0625,
-
SUM(
case
when
date =
'2013-06-26'
then
num
else
0
end)
as v_0626,
-
SUM(
case
when
date =
'2013-06-27'
then
num
else
0
end)
as v_0627,
-
SUM(
case
when
date =
'2013-06-28'
then
num
else
0
end)
as v_0628,
-
SUM(
case
when
date =
'2013-06-29'
then
num
else
0
end)
as v_0629,
-
SUM(
case
when
date =
'2013-06-30'
then
num
else
0
end)
as v_0630
-
from tab
-
group
by col1,col2,item
-
) v