公共表表达式上的SQL数据透视表

时间:2014-09-24 15:23:43

标签: sql tsql sql-server-2008-r2 pivot-table

我正在尝试使用公用表表达式来执行数据透视表,但我的数据透视表在透视列中返回NULL值。当我从cte中选择*时,我的结果会像我期望的那样返回。我可以使用一些帮助来弄清楚为什么我的数据透视表不能正常工作。

我的公用表表达式连接两个看起来像这样的表:

ProductionLine

ID | ProductionLine
--------------------
1  | Line A
2  | Line B

ProductionData

ID | ProductionLine_ID | UnitsProduced | ProductionDate
-------------------------------------------------------
1  | 1                 | 200           | 2014-09-18
2  | 2                 | 50            | 2014-09-18
3  | 1                 | 100           | 2014-09-19

所有ID都是int字段。 UnitsProduced是一个int字段。 ProductionDate是一个日期时间字段

这是我的SQL查询

;with cte as (select pl.ProductionLine as ProductionLine, pd.ProductionDate as ProductionDate, pd.UnitsProduced as UnitsProduced 
from ProductionLine pl
join
ProductionData pd on pl.ID = pd.ProductionLine_ID
)

select * from 
(
    select ProductionLine, 
    ProductionDate, 
    UnitsProduced
    from  cte
) x
pivot
(
    max(UnitsProduced) 
    for ProductionLine in ([Line A])
) pvt

我应该得到一个看起来像这样的结果:

ProductionDate | Line A
-----------------------
2014-09-18     | 200
2014-09-19     | 100

但是,我的结果如下:

ProductionDate | Line A
-----------------------
2014-09-18     | NULL
2014-09-19     | NULL

任何帮助将不胜感激

由于

1 个答案:

答案 0 :(得分:1)

如果数据有NULL,那么看看select子句会做这样的事情是非常常见的:

选择 ISNULL([FieldName],0)作为[FieldName] FROM SOMTEABLE

对于使用PIVOT的查询,它没有什么不同,您仍然可以通过SELECT clause解决NULL的问题,尽管这里的一个问题是您使用过" select * "并且此快捷方式隐藏了您可以解决问题的位置。

使用CTE的语法。注意什么是"选择*"现已详细说明,ISNULL(.....,0)已使用。

;WITH
      cte
      AS (
            SELECT
                  pl.ProductionLine AS ProductionLine
                , pd.ProductionDate AS ProductionDate
                , pd.UnitsProduced  AS UnitsProduced
            FROM ProductionLine pl
                  JOIN ProductionData pd
                              ON pl.ID = pd.ProductionLine_ID
            )

SELECT
      ISNULL([Line A], 0) [Line A]
    , ISNULL([Line B], 0) [Line B]
FROM (
      SELECT
            ProductionLine
          , ProductionDate
          , UnitsProduced
      FROM cte
      ) x
PIVOT
      (
      MAX(UnitsProduced)
      FOR ProductionLine IN ([Line A], [Line B])
      ) pvt
;

我个人不建议使用CTE,除非有明确需要它,这里不是真的,一个简单的子查询将完全相同的工作,语法稍微简单。 / p>

SELECT
      ISNULL([Line A], 0) [Line A]
    , ISNULL([Line B], 0) [Line B]
FROM (
      SELECT
            pl.ProductionLine AS ProductionLine
          , pd.ProductionDate AS ProductionDate
          , pd.UnitsProduced  AS UnitsProduced
      FROM ProductionLine pl
            JOIN ProductionData pd
                        ON pl.ID = pd.ProductionLine_ID
      ) x
PIVOT
      (
      MAX(UnitsProduced)
      FOR ProductionLine IN ([Line A], [Line B])
      ) pvt
;

See this working at SQLFiddle

COALESCE()ISNULL()

我在上面使用了ISNULL(),这是特定于TSQL的,PIVOT语法也是如此。 Stackoverflow建议尽可能使用标准SQL,因此请注意,在上述查询中可以使用COALESCE()代替ISNULL()。但也要注意那些功能并不完全相同。