我想保持这种一般性,所以如果没问题,我宁愿不使用我的特定数据集。
我的一般例子:我有一张订单很多的客户表。我想要一个数据透视表,显示每个客户每个月(或一般时间范围)有多少订单。假设我想添加一个列,显示该客户最近订购的日期。
所以表格如下:
CustomerID - January - February - March - April - May - MostRecentOrder
0001 - 2 - 3 - 1 - 1 - 1 - 2013/5/18
0002 - 1 - 0 - 1 - 0 - 1 - 2013/5/06
0003 - 0 - 1 - 4 - 1 - 2 - 2013/5/11
0004 - 2 - 0 - 0 - 1 - 0 - 2013/4/28
我试图在http://sqlfiddle.com/#!6/cbbad/1处找到一个正在运行的平台,但我显然比我在动态枢轴上的想法更糟糕。
答案 0 :(得分:2)
如果您想为每位客户添加最新日期,则可以使用max(orderdate) over(partition by customerId)
:
select customer.CustomerID,
o.OrderDate,
max(o.orderdate) over(partition by customer.customerid) mostrecentorder
from Customers as customer
join Orders as o
on customer.CustomerID = o.customerid;
您的完整代码类似于:
declare @start DATE = '2012-01-01';
declare @end DATE = DATEADD(dd,-(DAY(GETDATE())-1),GETDATE());
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
with months (dateList)
AS
(
SELECT @start
UNION ALL
SELECT DATEADD(month,1,dateList)
from months
where DATEADD(month,1,dateList)<=@end
)
select dateList
into #tempDates
from months
option (maxrecursion 0);
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(varchar(10), datelist, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = '
select *
from
(
select customer.CustomerID,
o.OrderDate,
max(o.orderdate) over(partition by customer.customerid) mostrecentorder
from Customers as customer
join Orders as o
on customer.CustomerID = o.customerid
) x
pivot
(
Count(OrderDate)
for OrderDate in ('+ @cols + ')
)y'
execute sp_executesql @query
如果您想按月显示数据(您在上面的结果中显示),那么您可以稍微更改代码以使用DATENAME:
declare @start DATE = '2012-01-01';
declare @end DATE = DATEADD(dd,-(DAY(GETDATE())-1),GETDATE());
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
with months (dateList)
AS
(
SELECT @start
UNION ALL
SELECT DATEADD(month,1,dateList)
from months
where DATEADD(month,1,dateList)<=@end
)
select dateList
into #tempDates
from months
option (maxrecursion 0);
select @cols = STUFF((SELECT ',' + QUOTENAME(mth)
from
(
select datepart(month, datelist) so, datename(month, datelist) mth
from #tempDates
) d
group by so, mth
order by so, mth
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = '
select customerId, '+@cols+', mostrecentorder
from
(
select customer.CustomerID,
datename(month, o.OrderDate) orderDate,
max(o.orderdate) over(partition by customer.customerid) mostrecentorder
from Customers as customer
join Orders as o
on customer.CustomerID = o.customerid
) x
pivot
(
Count(OrderDate)
for OrderDate in ('+ @cols + ')
)y'
execute sp_executesql @query;
见SQL Fiddle with Demo。这将得到一个结果:
| CUSTOMERID | JANUARY | FEBRUARY | MARCH | APRIL | MAY | JUNE | JULY | AUGUST | SEPTEMBER | OCTOBER | NOVEMBER | DECEMBER | MOSTRECENTORDER |
|------------|---------|----------|-------|-------|-----|------|------|--------|-----------|---------|----------|----------|----------------------------|
| 3 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | May, 03 2013 00:00:00+0000 |
| 2 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | May, 13 2013 00:00:00+0000 |
| 1 | 1 | 2 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | May, 23 2013 00:00:00+0000 |