-1

我可以使用循环根据计算创建可变数量的列吗?

表 A:包含 id、name、date、item 列。它显示谁在哪一天购买了一件物品。每次购买商品时,名称都会出现多次。id 是唯一的。

表 B:有名称,开始日期。它显示名称何时开始工作。

(我知道如何将 name 与 begindate 相关联,所以它实际上不在下面的伪代码中。)

表 C 是我希望我的结果看起来像的样子:

name   itemsday1 itemsday2 itemsday3... itemsdayn

第二列对应于今天购买的物品,最后一列对应于名称开始日期之前购买的物品。列数需要根据最早开始的人而有所不同。我希望我的查询循环并为从 begindate 到今天的每一天创建一个列,它计算当天 Name 购买的商品数量。

伪代码:

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 可以做到这一点吗?你能帮我把它固化成真正的代码吗?谢谢。

4

3 回答 3

0

关于动态旋转数据的 SO 有一些答案 - 这是我提供的答案,知道它是一件有用的事情。

sql server 2008 基于序数值的动态透视

通过使用 XML PATH 运算符,您还可以在结果集中获得体面的列名。

于 2012-06-12T20:45:01.570 回答
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
于 2012-06-12T18:53:33.743 回答
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);
于 2012-06-12T18:55:08.370 回答