PIVOT表返回所有空数据

时间:2016-12-07 00:04:40

标签: sql sql-server

考虑这个问题:

SELECT *
FROM (
  SELECT 
    userid,
    FORMAT(datecreated, 'yyyy-MM') AS purchasemonth,
    COALESCE(amount + tip, 0) AS amt
  FROM invoice
) AS SourceTable

产生如下输出:

enter image description here

这个数据透视查询我想在每个月总结:

SELECT
  userid,
  COALESCE([2016-08-01], 0) AS [2016-08-01],
  COALESCE([2016-09-01], 0) AS [2016-09-01]
FROM (
  SELECT 
    userid,
    FORMAT(datecreated, 'yyyy-MM') AS purchasemonth,
    COALESCE(amount + tip, 0) AS amt
  FROM invoice
) AS SourceTable
PIVOT
(
  SUM(amt)
  FOR purchasemonth IN ([2016-08-01], [2016-09-01])
) AS PivotTable

产生如下输出:

enter image description here

原始查询的输出中根本没有NULL数据。 PIVOT查询的输出只是空数据(合并为0)。但我无法弄清楚为什么PIVOT没有像我预期的那样对数据求和。我希望PIVOT输出中没有NULL数据。

如何修复查询以按预期运行?

1 个答案:

答案 0 :(得分:1)

您的派生表中的

PurchaseMonth字符串,其中没有 DAY ,您将其与进行比较日期,其中包含值/列名称的天数:

所以主要问题是这一行:

FOR purchasemonth IN ([2016-08-01], [2016-09-01])

FOR purchasemonth IN ([2016-08], [2016-09])

更改后,您还需要更改COALESCE()语句

你应该得到你想要的东西。

SELECT
  userid,
  COALESCE([2016-08], 0) AS [2016-08-01],
  COALESCE([2016-09], 0) AS [2016-09-01]
FROM (
  SELECT 
    userid,
    FORMAT(datecreated, 'yyyy-MM') AS purchasemonth,
    COALESCE(amount + tip, 0) AS amt
  FROM invoice
) AS SourceTable
PIVOT
(
  SUM(amt)
  FOR purchasemonth IN ([2016-08], [2016-09])
) AS PivotTable

如果您希望01保留数天,则只需将Derived Table定义更改为日期或以格式包含该日期

所以,如果你想走这条路线,改变这一行:

FORMAT(datecreated, 'yyyy-MM') AS purchasemonth,

DATEADD(day,1-DAY(datecreated),datecreated) AS purchasemonth,

您也可以使用此

FORMAT(datecreated, 'yyyy-MM-dd') AS purchasemonth,

但如果您不需要,FORMAT会产生性能影响,您没有理由介绍。

SELECT
  userid,
  COALESCE([2016-08-01], 0) AS [2016-08-01],
  COALESCE([2016-09-01], 0) AS [2016-09-01]
FROM (
  SELECT 
    userid,
    DATEADD(day,1-DAY(datecreated),datecreated) AS purchasemonth,
    COALESCE(amount + tip, 0) AS amt
  FROM invoice
) AS SourceTable
PIVOT
(
  SUM(amt)
  FOR purchasemonth IN ([2016-08-01], [2016-09-01])
) AS PivotTable