【问题标题】:Get 12 month name with data count using SQL Server?使用 SQL Server 获取 12 个月的名称和数据计数?
【发布时间】:2017-08-28 12:28:39
【问题描述】:

我创建了一个查询以获取 12 个月的名称并获取该月的计数。使用我的查询,我按月获取数据并获取月份名称。

但在我的查询中,如果 6 月份的表中没有任何数据,我将不会获得 6 月份的条目。我希望也显示 6 月份,数据为 0。怎么能这样做?我不知道。

这是我的查询:

DECLARE @year nvarchar(max)
SELECT  @year = year(getdate())

SELECT  
    MONTH(InsertDateTime) AS m,
    FORMAT(InsertDateTime, 'MMM-yy') AS Month,
    COUNT(InsertDateTime) AS tally
FROM
    Comments
WHERE  
    YEAR(InsertDateTime) = @year
GROUP BY 
    FORMAT(InsertDateTime, 'MMM-yy'), MONTH(InsertDateTime)

这是我的回报:

m | Month | tally
1   Jan-17    1
2    Feb-17   1 
3    Mar-17   10 
4    Apr-17   15  
5    May-17   20
8    Aug-17   25

这是我预期的 o/p:

m | Month | tally
1   Jan-17    1
2    Feb-17   1 
3    Mar-17   10 
4    Apr-17   15  
5    May-17   20
6    June-17  0
7    July-17  0
8    Aug-17   25
9    Sep-17    0
10   Oct-17    0
11   Nav-17    0
12   Dec-17    0

这个返回数据是正确的,但是这里我不返回其他月份。像 6 月、7 月、9 月、10 月、导航、12 月 mont 条目在表中不可用。我希望这个挖矿月也有 0 值的计数。

【问题讨论】:

标签: sql-server


【解决方案1】:

使用临时日历表生成 12 个月:

/* @StartDate = truncate `getdate()` to the start of the year: */
declare @StartDate datetime = dateadd(year , datediff(year , 0, getdate()), 0)

;with Months as (
select top (12) 
     m = row_number() over (order by number)
   ,[Month] = dateadd(month, row_number() over (order by number) -1, @StartDate)
  , NextMonth = dateadd(month, row_number() over (order by number), @StartDate)
  from master.dbo.spt_values
)
select 
    m.m
  , Month = format(m.Month, 'MMM-yy')
  , tally = count(c.InsertDateTime)
from Months m
  left join Comments c
    on c.InsertDateTime >= m.Month
   and c.InsertDateTime < m.NextMonth
group by m.m, format(m.Month, 'MMM-yy')
order by m

rextester 演示:http://rextester.com/NNVI43016

返回:

+----+--------+-------+
| m  | Month  | tally |
+----+--------+-------+
|  1 | Jan-17 |     3 |
|  2 | Feb-17 |     0 |
|  3 | Mar-17 |     2 |
|  4 | Apr-17 |     0 |
|  5 | May-17 |     0 |
|  6 | Jun-17 |     0 |
|  7 | Jul-17 |     0 |
|  8 | Aug-17 |     0 |
|  9 | Sep-17 |     0 |
| 10 | Oct-17 |     0 |
| 11 | Nov-17 |     0 |
| 12 | Dec-17 |     1 |
+----+--------+-------+

这有一个额外的优势,它不会在更大的表Comments 中的列上调用函数,而是使用 SARGable 条件进行连接。

参考:

【讨论】:

  • 我已经尝试过这个解决方案,但我没有得到六月、七月的月份名称,也没有按月排序
  • @Edit 我添加了一个演示并包含一个order by。请仔细检查您对代码的修改,以确认您已删除 where 子句,该子句会导致 left join 隐式变为 inner join..
  • @Edit 乐于助人!
  • 你好 SqlZim 我需要一些帮助和解决方案,在我的表中使用这个查询最多可以存储 10 万个数据,所以这个查询运行时间最多需要 1 分钟,所以我希望在 1 或 2 秒内数据得到所以怎么能做到这一点。我创建了缺失的索引并显示了执行计划。
【解决方案2】:

要么加入派生表:

SELECT s.m,s.month,COALESCE(t.tally,0) as tally
FROM (SELECT 1 as m, 'Jan-17' as Month UNION ALL
      SELECT 2 as m, 'Feb-17' as Month UNION ALL
      ...) s  
LEFT JOIN (Your Query) t
 ON(s.m = t.m and s.month = t.month)

或者,如果您已经有一个 time 表,那么请改用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2020-05-29
    相关资源
    最近更新 更多