SQL Server查询使用null或0值填充空记录

时间:2015-10-21 10:25:30

标签: sql sql-server sql-server-2008

我在SQL Server查询中有一个代码,列出了每年(列)和每月(行)表格中特定租户销售的表格式表示。

这是我认为与发布相关的部分代码

SELECT tenantcode
       ,datename(month, date) [month]
       ,isnull(sum(case when year(DATE) = @Year1  then sales end), 0) as 'Year1'
       ,isnull(sum(case when year(DATE) = @Year2 then sales end), 0) as 'Year2'
       ,isnull(sum(case when year(DATE) = @Year3 then sales end), 0) as 'Year3'
       ,isnull(sum(case when year(DATE) =  @Year4 then sales end), 0) as 'Year4'
       ,isnull(sum(case when year(DATE) = @Year5 then sales end), 0) as 'Year5'
FROM TenantSales 
GROUP BY  datename(month,date), tenantcode
ORBDER BY   datepart(MM,DATENAME(MONTH, DATE) + '01 2000')

请注意@Year是根据用户选择制定的5年变量。在这个例子2008-2012。特定租户于2008年5月开始,因此销售仅从2008年5月开始提供。代码生成此输出。 (例如)

enter image description here

我希望实现的目标是包括所有这些月份

enter image description here

当租户的销售在1月份开始或可用时,代码工作得很好,但是在我提到的实例中,它没有。

我正在使用SQL Server 2008

3 个答案:

答案 0 :(得分:2)

您需要所有月份的清单。对于单个租户(如问题中所述),您可以执行以下操作:

with months as (
      select cast('2015-01-01' as date) as d
      union all
      select dateadd(month, 1, months.d)
      from months
      where months.d < cast('2015-12-01' as date)
     )
SELECT tenantcode,
       datename(m.d, date) [month],
       isnull(sum(case when year(DATE) = @Year1  then sales end), 0) as Year1,
       isnull(sum(case when year(DATE) = @Year2 then sales end), 0) as Year2,
       isnull(sum(case when year(DATE) = @Year3 then sales end), 0) as Year3,
       isnull(sum(case when year(DATE) = @Year4 then sales end), 0) as Year4,
       isnull(sum(case when year(DATE) = @Year5 then sales end), 0) as Year5
FROM months m LEFT JOIN
     TenantSales CROSS JOIN
     ON month(date) = month(m.d)
GROUP BY datename(month, m.d), tenantcode
ORBDER BY month(m.d);

请注意,您只应对字符串和日期名称使用单引号。您不应该对列别名使用单引号,因为这可能会导致混淆。

答案 1 :(得分:1)

您希望包含所有月份,但正在针对不包含所有月份的数据运行查询。您需要加入包含所有月份的另一个表:

SELECT tenants.tenantcode
       ,months.monthname
       ,isnull(sum(case when year(t.DATE) = @Year1  then sales end), 0) as 'Year1'
       ,isnull(sum(case when year(t.DATE) = @Year2 then sales end), 0) as 'Year2'
       ,isnull(sum(case when year(t.DATE) = @Year3 then sales end), 0) as 'Year3'
       ,isnull(sum(case when year(t.DATE) =  @Year4 then sales end), 0) as 'Year4'
       ,isnull(sum(case when year(t.DATE) = @Year5 then sales end), 0) as 'Year5'
FROM 
(
SELECT
    Number
    ,DATENAME(MONTH, '2015-' + CAST(Number as varchar(2)) + '-1') monthname
FROM master..spt_values
WHERE Type = 'P' and Number between 1 and 12
) months

CROSS JOIN
(
    SELECT DISTINCT tenantcode
    FROM TenantSales
) tenants    

LEFT JOIN TenantSales t
ON months.monthname = datename(month,t.date)
AND tenants.tenantcode = t.tenantcode

GROUP BY  months.monthname, months.number, tenants.tenantcode
ORDER BY   months.number

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/697f4ee6-35d1-403d-a9f7-caecaf1ba479/all-monthnames-and-month-numbers-in-sql-server

生成月份表

答案 2 :(得分:1)

请改为尝试:

;WITH months(d) as
(
  SELECT dateadd(m, x, 0)
  FROM (values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) x(x)
)
SELECT 
  tenantcode,
  datename(month, m.d) [month],
  isnull(sum(case when year(DATE) = @Year1  then sales end), 0) as Year1,
  isnull(sum(case when year(DATE) = @Year2 then sales end), 0) as Year2,
  isnull(sum(case when year(DATE) = @Year3 then sales end), 0) as Year3,
  isnull(sum(case when year(DATE) = @Year4 then sales end), 0) as Year4,
  isnull(sum(case when year(DATE) = @Year5 then sales end), 0) as Year5
FROM
  months m
LEFT JOIN
  TenantSales ts
ON
  month(date) = month(m.d)
GROUP BY
  datename(month, m.d),m.d, tenantcode
ORDER BY
  m.d