Sql server 透视表视图数据中的sql连续列值
我在这个结构的表格中有数据:Sql server 透视表视图数据中的sql连续列值,sql-server,pivot,Sql Server,Pivot,我在这个结构的表格中有数据: Region | Date | Value A | 01/01/2014 | 100 A | 01/20/2014 | 50 A | 01/02/2014 | 200 A | 01/05/2014 | 300 B | 01/01/2014 | 50 B | 02/15/2014 | 70 B | 02/25/2014 | 50
Region | Date | Value
A | 01/01/2014 | 100
A | 01/20/2014 | 50
A | 01/02/2014 | 200
A | 01/05/2014 | 300
B | 01/01/2014 | 50
B | 02/15/2014 | 70
B | 02/25/2014 | 50
C | 05/02/2014 | 70
我正在尝试使用T-SQL查询创建这样的透视视图:
Region | Jan-2014 | Feb-2014 | Mar-014 | Apr-2014 | May-2014 | -> thru desired month-year
A | 150 | 200 | 0 | 0 | 300 |
B | 50 | 120 | 0 | 0 | 0 |
C | 0 | 0 | 0 | 0 | 70 |
请注意,需要聚合给定区域在同一个月内的多个值
没有记录的月份仍应显示为零值列(例如:3月和4月)
我厌倦了使用pivot选项,比如Roll up等等,但似乎无法实现这一点
非常感谢您的帮助
谢谢。您之所以没有这些月份的结果,是因为您缺少以列为轴心的日期 有几种方法可以做到这一点。您可以对查询的
部分中的中的所有日期值进行硬编码,以便显示以下列:
select Region,
isnull([Jan-2014], 0) [Jan-2014], isnull([Feb-2014], 0) [Feb-2014],
isnull([Mar-2014], 0) [Mar-2014], isnull([Apr-2014], 0) [Apr-2014],
isnull([May-2014], 0) [May-2014], isnull([Jun-2014], 0) [Jun-2014],
isnull([Jul-2014], 0) [Jul-2014], isnull([Aug-2014], 0) [Aug-2014],
isnull([Sep-2014], 0) [Sep-2014], isnull([Oct-2014], 0) [Oct-2014],
isnull([Nov-2014], 0) [Nov-2014], isnull([Dec-2014], 0) [Dec-2014]
from
(
select left(datename(month, t.date), 3) +'-'
+ cast(year(t.date) as char(4)) monthYear,
t.region,
t.value
from yt t
) src
pivot
(
sum(value)
for monthYear in ([Jan-2014], [Feb-2014], [Mar-2014], [Apr-2014],
[May-2014], [Jun-2014], [Jul-2014], [Aug-2014],
[Sep-2014], [Oct-2014], [Nov-2014], [Dec-2014])
) piv;
看
另一种方法是创建一个可以在查询中使用的日期表。创建后,您可以对表使用左联接
,以便返回所有要显示的日期。您可以创建递归查询以在透视查询中生成此列表,也可以使用日期列表填充表。递归查询与此类似:
;with dates (startDate, endDate) as
(
select min(date), cast('2014-12-31' as date)
from yt
union all
select dateadd(m, 1, startDate), enddate
from dates
where month(startDate) + 1 <= month(enddate)
)
select startDate
from dates;
看。您可以将其用作PIVOT查询的一部分,但仍然需要手工为PIVOT的in
子句中的所有日期编码
我猜您希望使用此查询的动态SQL版本,以便根据您的需要更改日期。动态版本将是:
DECLARE @cols AS NVARCHAR(MAX),
@colsNull AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startdate datetime = '2014-01-01',
@enddate datetime = '2014-12-01'
;with dates (startDate, endDate) as
(
select @startdate, @enddate
from yt
union all
select dateadd(m, 1, startDate), enddate
from dates
where dateadd(m, 1, startDate) <= enddate
)
select @cols = STUFF((SELECT ',' + QUOTENAME(left(datename(month, d.startdate), 3) +'-'
+ cast(year(d.startdate) as char(4)))
from dates d
-- where startdate >= '2014-01-01' and startdate <= '2014-06-01'
group by d.startdate
order by d.startdate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,''),
@colsNull = STUFF((SELECT ', isnull(' + QUOTENAME(left(datename(month, d.startdate), 3) +'-'
+ cast(year(d.startdate) as char(4)))+', 0) as '+QUOTENAME(left(datename(month, d.startdate), 3) +'-'
+ cast(year(d.startdate) as char(4)))
from dates d
-- where startdate >= '2014-01-01' and startdate <= '2014-06-01'
group by d.startdate
order by d.startdate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
from dates
set @query = 'SELECT region, ' + @colsNull + ' from
(
select left(datename(month, t.date), 3) +''-''
+ cast(year(t.date) as char(4)) monthYear,
t.region,
t.value
from yt t
) x
pivot
(
sum(value)
for monthyear in (' + @cols + ')
) p '
execute(@query);
输出不正确。应该是地区A&Jan->650
谢谢!你对我的数据状况产生了积极的影响。还可以合并两个pivot查询的结果吗?查询将具有相同的列。感谢你help@user2365233您可以考虑使用UNIONHi,我正在考虑使用您建议的透视表查询创建一个视图,但由于变量的原因,无法保存该视图。有没有其他方法可以创建产生相同结果的视图?@user2365233您不能在视图中使用动态sql。您必须使用存储过程!你能分享一个我如何将你的查询转换成存储过程的例子吗?
DECLARE @cols AS NVARCHAR(MAX),
@colsNull AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startdate datetime = '2014-01-01',
@enddate datetime = '2014-12-01'
;with dates (startDate, endDate) as
(
select @startdate, @enddate
from yt
union all
select dateadd(m, 1, startDate), enddate
from dates
where dateadd(m, 1, startDate) <= enddate
)
select @cols = STUFF((SELECT ',' + QUOTENAME(left(datename(month, d.startdate), 3) +'-'
+ cast(year(d.startdate) as char(4)))
from dates d
-- where startdate >= '2014-01-01' and startdate <= '2014-06-01'
group by d.startdate
order by d.startdate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,''),
@colsNull = STUFF((SELECT ', isnull(' + QUOTENAME(left(datename(month, d.startdate), 3) +'-'
+ cast(year(d.startdate) as char(4)))+', 0) as '+QUOTENAME(left(datename(month, d.startdate), 3) +'-'
+ cast(year(d.startdate) as char(4)))
from dates d
-- where startdate >= '2014-01-01' and startdate <= '2014-06-01'
group by d.startdate
order by d.startdate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
from dates
set @query = 'SELECT region, ' + @colsNull + ' from
(
select left(datename(month, t.date), 3) +''-''
+ cast(year(t.date) as char(4)) monthYear,
t.region,
t.value
from yt t
) x
pivot
(
sum(value)
for monthyear in (' + @cols + ')
) p '
execute(@query);
| REGION | JAN-2014 | FEB-2014 | MAR-2014 | APR-2014 | MAY-2014 | JUN-2014 | JUL-2014 | AUG-2014 | SEP-2014 | OCT-2014 | NOV-2014 | DEC-2014 |
----------------------------------------------------------------------------------------------------------------------------------------------
| A | 650 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| B | 50 | 120 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| C | 0 | 0 | 0 | 0 | 70 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |