【问题标题】:SQL Pivot questionSQL 数据透视问题
【发布时间】:2010-01-05 13:28:24
【问题描述】:

我很难理解我尝试使用 SQL Server 2005 构建的查询。

我有一张桌子,我们称之为销售:

SaleId (int) (pk) EmployeeId (int) SaleDate(datetime)

我想生成一份报告,列出给定数据范围内员工每天的销售总数。

因此,例如,我希望查看 2009 年 12 月 1 日至 2009 年 12 月 31 日的所有销售额,输出如下:

EmployeeId  Dec1   Dec2 Dec3   Dec4

1            10    10    1     20
2            25    10    2      2

..etc 但是日期需要灵活。

我已经搞砸了使用枢轴,但似乎不太明白,欢迎任何想法!

【问题讨论】:

    标签: sql-server pivot


    【解决方案1】:

    这是一个完整的例子。您可以根据需要更改日期范围。

    use sandbox;
    create table sales (SaleId int primary key, EmployeeId int, SaleAmt float, SaleDate date);
    
    insert into sales values (1,1,10,'2009-12-1');
    insert into sales values (2,1,10,'2009-12-2');
    insert into sales values (3,1,1,'2009-12-3');
    insert into sales values (4,1,20,'2009-12-4');
    
    insert into sales values (5,2,25,'2009-12-1');
    insert into sales values (6,2,10,'2009-12-2');
    insert into sales values (7,2,2,'2009-12-3');
    insert into sales values (8,2,2,'2009-12-4');
    
    SELECT * FROM
          (SELECT EmployeeID, DATEPART(d, SaleDate) SaleDay, SaleAmt
                      FROM sales
                      WHERE SaleDate between '20091201' and '20091204'
                      ) src
    PIVOT (SUM(SaleAmt) FOR SaleDay
    IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31])) AS pvt;
    

    结果(实际上将列出 31 列(所有可能的月份天数),但我只显示前 4 个):

    EmployeeID      1       2       3       4
    1               10      10      1       20
    2               25      10      2       2
    

    【讨论】:

    • 嘿,这太棒了...我不知道如何动态生成列 - 好像你做到了,赞!
    【解决方案2】:

    我稍微修改了一下,我认为这就是你可以用PIVOT 做到这一点的方法:

    select  employeeid
    ,       [2009/12/01] as Dec1
    ,       [2009/12/02] as Dec2
    ,       [2009/12/03] as Dec3
    ,       [2009/12/04] as Dec4
    from    sales pivot (
            count(saleid) 
            for saledate
            in ([2009/12/01],[2009/12/02],[2009/12/03],[2009/12/04])
        ) as pvt
    

    (这是我的桌子:

    CREATE TABLE [dbo].[sales](
    [saleid] [int] NULL,
    [employeeid] [int] NULL,
    [saledate] [date] NULL
    

    数据为:emp1 为 '2009/12/01' 10 行,emp2 为 '2009/12/01' 25 行,emp1 为 '2009/12/02' 10 行等)

    现在,我必须说,这是我第一次使用PIVOT,也许我没有掌握它,但这对我来说似乎毫无用处。我的意思是,如果你不能做任何事情来动态指定列,那么有一个交叉表有什么好处?

    编辑:好的- dcp 的答案就是这样。诀窍是,您不必显式命名 SELECT 列表中的列,* 实际上会正确扩展为第一个“未透视”列的列,以及 FOR 中出现的每个值的动态生成列。 PIVOT 构造中的 IN 子句。

    【讨论】:

    • 所有可能的项目都必须在 FOR..IN 子句中列出。你是对的,它不是动态的。但是当我看到在 SQL 语句中使用 PIVOT 时,我知道它要做什么。否则,一堆 Case 语句可能会尝试做任何事情(哦,我忘了,看看文档。)。不错的第一次尝试。 +1
    • 感谢 GuinnessFan。是的,我熟悉在 MySQL 中做同样事情的 CASE 语句。但是,能够为此使用明确的语法仍然很好。再次感谢!干杯
    猜你喜欢
    • 2010-11-27
    • 2015-06-08
    • 2011-10-16
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    相关资源
    最近更新 更多