请教一个按日期统计的SQL

zedan 2009-07-08 02:05:43
Table A
ID WID Date
1 1 2009/7/1
2 1 2009/7/10
3 1 2009/7/12
4 2 2009/7/1
5 2 2009/8/1

Table W
WID WName
1 WA
2 WB
3 WC
4 WD

传入日期 start-2009/7/1, end-2009/7/20
求这日期内每个星期在Table A的数据统计和
即返回
ID WName 2009/7/1-2009/7/7 2009/7/8-2009/7/15 2009/7/16-2009/7/20
1 WA 1 2 0
2 WB 1 0 0
3 WC 0 0 0
4 WD 0 0 0

求SQL?
...全文
119 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
kajaje 2009-07-08
  • 打赏
  • 举报
回复
参考下帮助丛书里的交叉数据报表,有些类似
子陌红尘 2009-07-08
  • 打赏
  • 举报
回复
create table A(ID int,WID int,Date datetime)
insert into A select 1,1,'2009/07/01'
insert into A select 2,1,'2009/07/10'
insert into A select 3,1,'2009/07/12'
insert into A select 4,2,'2009/07/01'
insert into A select 5,2,'2009/08/01'

create table W(WID int,WName varchar(10))
insert into W select 1,'WA'
insert into W select 2,'WB'
insert into W select 3,'WC'
insert into W select 4,'WD'
go


create procedure sp_test(@str datetime,@end datetime)
as
begin
declare @sql varchar(8000)
set @sql='select W.WID,W.WName'

while @str<@end
begin
set @sql=@sql+',['+convert(char(10),@str,111)+'-'+convert(char(10),(case when @str+6<@end then @str+6 else @end end),111)+']='
+'sum(case when Date between '''+convert(char(10),@str,111)+''' and '''
+convert(char(10),(case when @str+6<@end then @str+6 else @end end),111)+''' then 1 else 0 end)'
set @str=@str+7
end
set @sql=@sql+' from W left join A on A.WID=W.WID group by W.WID,W.WName '
exec(@sql)
end
go

exec sp_test '2009/7/1','2009/7/20'
go

/*
WID WName 2009/07/01-2009/07/07 2009/07/08-2009/07/14 2009/07/15-2009/07/20
----------- ---------- --------------------- --------------------- ---------------------
1 WA 1 2 0
2 WB 1 0 0
3 WC 0 0 0
4 WD 0 0 0
*/

drop procedure sp_test
drop table A,W
go
zedan 2009-07-08
  • 打赏
  • 举报
回复
以# htl258 (Tony)的例子,
如果 Student加多一行数据,
王五 语文 80, 他其它科目缺考,即都显示为0分,
如何写?
应该不一样写法吧?
pt1314917 2009-07-08
  • 打赏
  • 举报
回复
--> 测试数据: [A]
if object_id('[A]') is not null drop table [A]
create table [A] (ID int,WID int,Date datetime)
insert into [A]
select 1,1,'2009/7/1' union all
select 2,1,'2009/7/10' union all
select 3,1,'2009/7/12' union all
select 4,2,'2009/7/1' union all
select 5,2,'2009/8/1'
--> 测试数据: [W]
if object_id('[W]') is not null drop table [W]
create table [W] (WID int,WName varchar(2))
insert into [W]
select 1,'WA' union all
select 2,'WB' union all
select 3,'WC' union all
select 4,'WD'
go

--创建存储过程
create proc wsp
@star datetime,
@end datetime
as
declare @t table(star datetime,[end] datetime)
while(@star<=@end)
begin
if(dateadd(dd,7,@star)<=@end)
insert into @t select @star,dateadd(dd,6,@star)
else
insert into @t select @star,@end
set @star=dateadd(dd,7,@star)
end
declare @sql varchar(8000)
set @sql='select w.wid,w.wname'
select @sql=@sql+',['+convert(varchar(10),star,120)+'-'+convert(varchar(10),[end],120)+']=sum(
case when Date between '''+convert(varchar(10),star,120)+''' and '''+convert(varchar(10),[end],120)+''' then 1 else 0 end)'
from @t
set @sql=@sql+' from W left join a on a.wid=w.wid group by w.wid,w.wname'
exec(@sql)
go


--执行
exec wsp '2009/7/1','2009/7/20'

--结果:
wid wname 2009-07-01-2009-07-07 2009-07-08-2009-07-14 2009-07-15-2009-07-20
----------- ----- --------------------- --------------------- ---------------------
1 WA 1 2 0
2 WB 1 0 0
3 WC 0 0 0
4 WD 0 0 0
zzz1975 2009-07-08
  • 打赏
  • 举报
回复
粘贴一个例子

Create Table 表(year varchar(10),name varchar(10),value varchar(10))
--插入数据
insert into 表
select '2002','a','1' union
select '2002','b','4' union
select '2002','c','5' union
select '2003','a','7' union
select '2003','b','5' union
select '2003','c','4' union
select '2004','a','4'
select * from 表
--测试语句
DECLARE @SQL VARCHAR(8000)
SET @SQL='SELECT name'
SELECT @SQL= @SQL+
',MIN(CASE WHEN year = ''' + year + ''' THEN value END) [' + year + ']'
FROM (SELECT DISTINCT year FROM 表) A
SET @SQL=@SQL+' FROM 表 GROUP BY name'
exec (@SQL)
htl258_Tony 2009-07-08
  • 打赏
  • 举报
回复
--行列互转
/******************************************************************************************************************************************************
以学生成绩为例子,比较形象易懂

整理人:中国风(Roy)

日期:2008.06.06
******************************************************************************************************************************************************/

--1、行互列
--> --> (Roy)生成測試數據

if not object_id('Class') is null
drop table Class
Go
Create table Class([Student] nvarchar(2),[Course] nvarchar(2),[Score] int)
Insert Class
select N'张三',N'语文',78 union all
select N'张三',N'数学',87 union all
select N'张三',N'英语',82 union all
select N'张三',N'物理',90 union all
select N'李四',N'语文',65 union all
select N'李四',N'数学',77 union all
select N'李四',N'英语',65 union all
select N'李四',N'物理',85
Go
--2000方法:
动态:

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)'
from Class group by[Course]
exec('select [Student]'+@s+' from Class group by [Student]')


生成静态:

select
[Student],
[数学]=max(case when [Course]='数学' then [Score] else 0 end),
[物理]=max(case when [Course]='物理' then [Score] else 0 end),
[英语]=max(case when [Course]='英语' then [Score] else 0 end),
[语文]=max(case when [Course]='语文' then [Score] else 0 end)
from
Class
group by [Student]

GO
动态:

declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]
exec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')

生成静态:
select *
from
Class
pivot
(max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b

生成格式:
/*
Student 数学 物理 英语 语文
------- ----------- ----------- ----------- -----------
李四 77 85 65 65
张三 87 90 82 78

(2 行受影响)
*/

------------------------------------------------------------------------------------------
go
--加上总成绩(学科平均分)

--2000方法:
动态:

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+' then [Score] else 0 end)'
from Class group by[Course]
exec('select [Student]'+@s+',[总成绩]=sum([Score]) from Class group by [Student]')--加多一列(学科平均分用avg([Score]))

生成动态:

select
[Student],
[数学]=max(case when [Course]='数学' then [Score] else 0 end),
[物理]=max(case when [Course]='物理' then [Score] else 0 end),
[英语]=max(case when [Course]='英语' then [Score] else 0 end),
[语文]=max(case when [Course]='语文' then [Score] else 0 end),
[总成绩]=sum([Score]) --加多一列(学科平均分用avg([Score]))
from
Class
group by [Student]

go

--2005方法:

动态:

declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course] --isnull(@s+',','') 去掉字符串@s中第一个逗号
exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a
pivot (max([Score]) for [Course] in('+@s+'))b ')

生成静态:

select
[Student],[数学],[物理],[英语],[语文],[总成绩]
from
(select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时用avg([Score])
pivot
(max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b

生成格式:

/*
Student 数学 物理 英语 语文 总成绩
------- ----------- ----------- ----------- ----------- -----------
李四 77 85 65 65 292
张三 87 90 82 78 337

(2 行受影响)
*/

go

--2、列转行
--> --> (Roy)生成測試數據

if not object_id('Class') is null
drop table Class
Go
Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)
Insert Class
select N'李四',77,85,65,65 union all
select N'张三',87,90,82,78
Go

--2000:

动态:

declare @s nvarchar(4000)
select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第一个union all
+',[Score]='+quotename(Name)+' from Class'
from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列
order by Colid
exec('select * from ('+@s+')t order by [Student],[Course]')--增加一个排序

生成静态:
select *
from (select [Student],[Course]='数学',[Score]=[数学] from Class union all
select [Student],[Course]='物理',[Score]=[物理] from Class union all
select [Student],[Course]='英语',[Score]=[英语] from Class union all
select [Student],[Course]='语文',[Score]=[语文] from Class)t
order by [Student],[Course]

go
--2005:

动态:

declare @s nvarchar(4000)
select @s=isnull(@s+',','')+quotename(Name)
from syscolumns where ID=object_id('Class') and Name not in('Student')
order by Colid
exec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')

go
select
Student,[Course],[Score]
from
Class
unpivot
([Score] for [Course] in([数学],[物理],[英语],[语文]))b

生成格式:
/*
Student Course Score
------- ------- -----------
李四 数学 77
李四 物理 85
李四 英语 65
李四 语文 65
张三 数学 87
张三 物理 90
张三 英语 82
张三 语文 78

(8 行受影响)
*/
kajaje 2009-07-08
  • 打赏
  • 举报
回复
参考下帮助丛书里的交叉数据报表,大致相同。
usher_gml 2009-07-08
  • 打赏
  • 举报
回复
行列互换
-狙击手- 2009-07-08
  • 打赏
  • 举报
回复
类似行列互换,找找精华里

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧