我可以使用循环根据计算创建可变数量的列吗?
表A:列id,名称,日期,项目。它显示谁在哪一天买了一件商品。在购买商品时,名称会多次出现。 id是唯一的。
表B:有名字,请求。它显示名称何时开始工作。
(我知道如何将name与begindate联系起来,所以它不是真的在下面的伪代码中。)
表C是我想要的结果:
name itemsday1 itemsday2 itemsday3... itemsdayn
第二栏与今天购买的物品相对应,这是在名称之前购买的物品的最后一个物品。列数需要根据最早开始的人而有所不同。我希望我的查询循环并为每天创建一个列,从begindate到今天,它计算当天名称购买的项目数。
Psuedo代码:
declare mostd INT
select datediff(dd, begindate, getdate()) as spans into #span from B
set mostd = select max(spans) from #span
select
name
,while mostd !=0
begin
case when???
count(items)
end as column.mostd
mostd=mostd-1
end
end
from A (join B blah blah)
group by name
Results
NAME column4 column3 column2 column1 column0
James 9 8 7 6 NULL
Wade 5 4 3 NULL NULL
Bosh 2 1 NULL NULL NULL
Durant 0 9 8 NULL NULL
TSQL可以这样做吗?你能帮我把它固化成真正的代码吗?感谢。
答案 0 :(得分:0)
使用PIVOT运算符http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
可以实现更新:一个例子。它受到这篇伟大文章的启发:http://dotnetgalactics.wordpress.com/2009/10/23/using-sql-server-20052008-pivot-on-unknown-number-of-columns-dynamic-pivot/:
-- create table #items (id int, name varchar(40), date datetime, userid int)
-- create table #users (id int, name varchar(40), begindate datetime)
declare @dates varchar(4000)
declare @query varchar(4000)
SELECT @dates = STUFF(( SELECT DISTINCT
'],[' + cast(date as varchar(30))
FROM #items
ORDER BY '],[' + cast(date as varchar(30))
FOR XML PATH('')
), 1, 2, '') + ']'
set @query = 'SELECT * FROM (SELECT #users.name, date FROM #items
INNER JOIN #users ON #items.userid = #users.id) items
PIVOT (COUNT(date) FOR date IN (' + @dates + ')) pvt'
EXECUTE(@query)
结果:
name 2012-10-01 2012-10-02 2012-10-03 2012-10-04 2012-10-05 2012-10-06 2012-10-07
user1 0 0 1 0 0 1 0
user2 1 6 0 0 0 1 1
user3 1 1 7 0 0 3 0
user4 0 0 0 1 1 1 1
答案 1 :(得分:0)
您需要使用动态SQL来执行此操作。从
开始DECLARE @SelectSQL varchar(max) = "SELECT name";
然后执行你的while循环,跟踪字段名称的整数计数器(如果你真的想以相反的顺序执行此操作,则需要使用DATEDIFF(day,getdate(),begindate)并向后计数)。对于要表示列的每一天,输出以下内容:
SELECT @SelectSQL = @SelectSQL + ', (SELECT COUNT(id) FROM TableA where name = TableB.name AND [date] = ''' + CONVERT(varchar, @mostd) + ''') AS column' + str(@ColumnCounter)
然后,在循环之外,您将后续查询的其余部分:
@SelectSQL = @SelectSQL + ' FROM TableB';
注意,没有连接到TableA,因为在子查询中都会处理这一点。此外,出于同样的原因,您不需要GROUP BY.
修改:哎呀,忘记了最后一部分。
要执行此操作,只需运行:
EXEC (@SelectSQL);
答案 2 :(得分:0)
SO上有一些关于动态转动数据的答案 - 这是我提供的一个,这是一个有用的东西。
sql server 2008 dynamic pivot based on ordinal value
通过使用XML PATH运算符,您还可以在结果集中获得不错的列名。