好吧,下面是我写的一个查询的例子,它可以做某些事情与你想要的相似。它需要一组数据并根据开始年份动态调整。我只给了你第一个支点(用于价格)。如果要在第二列以及之后进行循环,则需要创建第二个动态选择字符串,然后再加入动态SQL中的新数据透视表。
declare @startYear int = 2010;
declare @startDate datetime = '1/1/2010 00:00:00.000';
declare @endYear int = year(getutcdate());
declare @endDate datetime = convert(datetime, '12/31/' + convert(nvarchar, @endYear) + ' 23:59:59.997');
-- our variables for string concatenation
declare @yearString nvarchar(max) = ''
, @piv1YearSelectionString nvarchar(max) = ''
, @query nvarchar(max) = ''
;
-- check for the existence of our temp table and dropping it
if exists (
select * from tempdb.dbo.sysobjects o
where o.xtype in ('U')
and o.id = object_id(N'tempdb..#rawData')
)
begin
drop table #rawData;
end
-- create our temp table
create table #rawData
(
EmployeeId nvarchar(50)
, InvoiceYear int
, Price money
, Cm nvarchar(50)
, St1 int
, St2 int
);
-- concatenate our strings with our year column names
while (@startYear <= @endYear)
begin
-- creates a string of values like [2010, 2011, ...]
set @yearString = @yearString + '[' + convert(nvarchar, @startYear) + ']';
-- creates a string of values like ['COALESCE(MAX[a].[2011], 0) as [Price2011], ...
set @piv1YearSelectionString = @piv1YearSelectionString + 'COALESCE(MAX([a].[' + convert(nvarchar, @startYear) + ']), 0) AS [Price' + convert(nvarchar, @startYear) + ']';
set @startYear = @startYear + 1;
-- adds commas to the strings
if @startYear <= @endYear
begin
set @yearString = @yearString + ', ';
set @piv1YearSelectionString = @piv1YearSelectionString + ', ';
end
end
;
-- build the query here
set @query = '
declare @sDate datetime = ''' + convert(varchar, @startDate) + ''';
declare @eDate datetime = dateadd(s, -1, dateadd(yyyy, 1, @sDate));
declare @stopDate datetime = ''' + convert(varchar, @endDate) + ''';
while @sDate < @stopDate
begin
-- uncomment the line below to see the dates
--select @sDate, @eDate;
-- collect your input table
insert #rawData (employeeId, invoiceYear, Price, Cm, St1, St2)
select
EmployeID
, year(InvoiceDate) as InvoiceYear
, Price
, Cm
, St1
, St2
from
<SourceQuery>
where
InvoiceDate between @sdate and @eDate
;
set @sDate = dateadd(yyyy, 1, @sDate);
set @eDate = dateadd(ms, -1, dateadd(yyyy, 1, @sDate));
end
-- dynamically pivot
select
a.EmployeeId
, ' + @piv1YearSelectionString + '
from
(
select
piv1.CompanyId, piv1.CompanyName, ' + @yearString + '
from
#rawData
pivot
(
max(Price)
for [invoiceYear] in (' + @yearString + ')
) as piv1
) a
group by
a.EmployeeId
order by
a.EmployeeId
';
-- run the query
execute(@query);
-- clean up
drop table #rawdata;
你尝试过这么远吗?我们很乐意提供帮助,但您也必须自己投入一些努力。 –
最近我已经转移到SQL编码。我已经通过了枢轴的几个门户。看起来Pivot可以将行转换为列,但是,我还没有任何线索如何实现我的场景。 –
这是绝对可行的,但在SQL Server中执行起来相当复杂,而且通常最终不得不做一些动态SQL。我最近也做了同样的事情,所以我可以提供帮助,但是如果你不熟悉SQL,可能会遇到一些你会遇到的问题。如果你不明白,请询问。 –