求 查最近七个月的一句SQL

xieganlin 2012-03-26 11:21:09
在表中存在Desc,startDate,EndDate三个字段, 现在要通过StartDate和EndDate取出最近七个月的数据,也就是把Desc由一列转成七列。效果如:
Desc1 Desc2 Desc3 Desc4 Desc5 Desc6 Desc7 startDate endDate
测试 测试 测试 2011-12-3 2012-2-4
测试2 测试2 测试2 测试2 测试2 2011-11-3 2012-3-4

此SQL应该如何写。
...全文
191 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

GO
IF OBJECT_ID('TBL')IS NOT NULL
DROP TABLE TBL
GO
CREATE TABLE TBL(
日期 DATE
)
GO
INSERT TBL
SELECT '2012-01-01' UNION ALL
SELECT '2012-07-01'
go
declare @date date
select @date=MAX(日期) from tbl
;with t
as(
select * from tbl
union all
select dateadd(MM,1,a.日期) from t a
where not exists(select * from tbl b
where b.日期=DATEADD(MM,1,a.日期)
)
and a.日期<@date
)
select *from t order by 日期

/*
首先生成这七个月的连续日期:
日期
2012-01-01
2012-02-01
2012-03-01
2012-04-01
2012-05-01
2012-06-01
2012-07-01
然后再行列转换成你要的那样
*/
黄_瓜 2012-03-26
  • 打赏
  • 举报
回复
--行列互转
/******************************************************************************************************************************************************
以学生成绩为例子,比较形象易懂

整理人:中国风(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 行受影响)
*/
黄_瓜 2012-03-26
  • 打赏
  • 举报
回复
行列转换。。。。





xieganlin 2012-03-26
  • 打赏
  • 举报
回复
Desc1 Desc2 Desc3(SGdone) Desc4(SGdone) Desc5(SGdone) Desc6 Desc7 startDate(2012-03-15) endDate(2012-05-15)
xieganlin 2012-03-26
  • 打赏
  • 举报
回复
Desc1 Desc2 Desc3 Desc4 Desc5 Desc6 Desc7 startDate endDate
SG done SG done SG done 2012-03-15 2012-05-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 xieganlin 的回复:]
在表中存在Desc,startDate,EndDate三个字段, 现在要通过StartDate和EndDate取出最近七个月的数据,也就是把Desc由一列转成七列。效果如:
Desc1 Desc2 Desc3 Desc4 Desc5 Desc6 Desc7 startDate endDate
测试 测试 测试 201……
[/Quote]

给出测试数据和结果。没怎么明白
xieganlin 2012-03-26
  • 打赏
  • 举报
回复
hhh 是显示在 desc3 desc4 desc5
xieganlin 2012-03-26
  • 打赏
  • 举报
回复
表 字段: id desc startdate enddate[BR/]
1 hhh 2012-03-10 2012-05-10[BR/]
显示结果: 一月 二月 三月 四月 五月 六月 七月[BR/]
id desc1 desc2 desc3 desc4 desc5 desc6 desc7 startdate enddate[BR/]
1 hhh hhh hhh 2012-03-10 2012-05-10[BR/]
koumingjie 2012-03-26
  • 打赏
  • 举报
回复

create table tb
([desc] varchar(100),
StartDate datetime,
EndDate Datetime
)

;create view vwt
AS
SELECT CONVERT(VARCHAR(10), DATEADD(month, a.number, b.StartDate) , 120) descDate,b.[desc]
FROM MASTER..spt_values a,tb b
WHERE a.[type] = 'p'
AND a.number BETWEEN 0 AND DATEDIFF(month, DATEADD(month, a.number, b.StartDate), DATEADD(month, a.number, b.EndDate))


insert into tb
select 'desc1','2012-02-01','2012-07-01' union all
select 'desc2','2012-05-01','2012-09-01'

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename(t.[descDate] ) +'=max(case when descDate='+quotename(t.[descDate],'''')+' then [desc] else '''' end)'
from (select distinct descDate from vwt) t order by t.descDate
exec('select [desc]'+@s+' from vwt group by [desc]')

you_tube 2012-03-26
  • 打赏
  • 举报
回复
数据库设计不是很完善,,,
胡搞一通,,,,
koumingjie 2012-03-26
  • 打赏
  • 举报
回复
上面的有问题,试试这个

create table tb
([desc] varchar(100),
StartDate datetime,
EndDate Datetime
)

;create view vwt
AS
SELECT CONVERT(VARCHAR(10), DATEADD(month, a.number, b.StartDate) , 120) descDate,b.[desc]
FROM MASTER..spt_values a,tb b
WHERE a.[type] = 'p'
AND a.number BETWEEN 0 AND DATEDIFF(month, DATEADD(month, a.number, b.StartDate), DATEADD(month, a.number, b.EndDate))


insert into tb select 'desc','2012-05-01','2012-09-01'


declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([descDate] ) +'=max(case when descDate='+quotename([descDate],'''')+' then [desc] else '''' end)'
from vwt
exec('select [desc]'+@s+' from vwt group by [desc]')
koumingjie 2012-03-26
  • 打赏
  • 举报
回复
用一个视图作为中间表,这样写法清楚点


create table tb
([desc] varchar(100),
StartDate datetime,
EndDate Datetime
)

;create view vwt
AS
SELECT CONVERT(VARCHAR(10), DATEADD(month, a.number, b.StartDate) , 120) descDate,b.[desc]
FROM MASTER..spt_values a,tb b
WHERE a.[type] = 'p'
AND a.number BETWEEN 0 AND DATEDIFF(month, DATEADD(month, a.number, b.StartDate), DATEADD(month, a.number, b.EndDate))


insert into tb select 'desc','2012-03-01','2012-07-01'

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([desc] + DATENAME(month,[descDate]) ) +'=max(case when descDate='+quotename([descDate],'''')+' then [desc] else '''' end)'
from vwt group by [desc],descDate
print(@s)
exec('select [desc]'+@s+' from vwt group by [desc]')

xieganlin 2012-03-26
  • 打赏
  • 举报
回复
现在是要根据StartDate和EndDate两个字段.
xieganlin 2012-03-26
  • 打赏
  • 举报
回复
可能表达不清楚吧,贴出来的是要显示的结果,是根据开始时间跟结束时间知道,如果开始时间是三月,结束时间是五月,那么desc3 ,desc4,desc5 ,显示的事同样的值,都是desc,在这个题贴出来的测试数据,desc1-7,在表中是不存的的。。。

22,302

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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