我正在运行以下查询以获取去年到本月的去年的每月数据计数。
SELECT dateName(month,tn.processstarttime) as reqMonth, count(ID) as requestCount, year(tn.processstarttime) as reqYear
FROM table A tn WHERE year(tn.processstarttime) in (year(DATEADD(MONTH, 0, GETDATE())),year(DATEADD(MONTH, -12, GETDATE())))
AND tn.processstarttime>DATEADD(MONTH, -12, GETDATE())
GROUP BY dateName(month,tn.processstarttime),year(tn.processstarttime)
order by dateName(month,tn.processstarttime),year(tn.processstarttime)
但是此查询未提供数据计数为0
的月份名称。
请支持包括数据计数为0
且值为0
的月份。
谢谢
答案 0 :(得分:2)
标准方法是使用所有年份和月份都必需的日历表,然后LEFT JOIN
对其结果进行处理。如果您的表中没有对应的记录,那么您将使用COALESCE
来获取这几个月的0
。参见下面的查询(我使用CTE获取日历表,最简单的方法是IMO):
;with MonthNames as (
select 1 MonthNo, 'January' MonthName
union all
select 2, 'February'
union all
select 3, 'March'
union all
select 4, 'April'
union all
select 5, 'May'
union all
select 6, 'June'
union all
select 7, 'July'
union all
select 8, 'August'
union all
select 9, 'September'
union all
select 10, 'October'
union all
select 11, 'November'
union all
select 12, 'December'
), Years as (
select 2017 Year union all select 2018 union all select 2019
), CalendarTable as (
select * from MonthNames cross join Years
)
select ct.MonthName,
ct.Year,
COALESCE(t.requestCount, 0) requestCount
from CalendarTable ct
left join (YOUR WHOLE SELECT) t
on t.Year = ct.Year and t.month = ct.MonthNo
答案 1 :(得分:1)
此答案可能与Michal Turczyn的答案相似,但有一些实质性差异:
不要太在意创建前两个CTE的差异,因为它们看上去无关紧要,只是样式问题。
重要的区别在于第三个CTE和过滤查询的方式,您的列名(processstarttime)提供了一个线索,它可以是一个非常大的表,因此,如果您在where子句中使用函数选定的表列,它将起作用,但是您的查询将不会被索引,并且性能可能会成为另一个问题
无关紧要,但也很重要的一点是,它涵盖了“去年到本月为止的去年的每月数据计数” PO的要求,而没有硬编码日期,它可以在视图或函数中,无需逐年修改...
WITH months AS (
SELECT 1 AS MonthNum, DATENAME(Month,DATEFROMPARTS(1,1,1)) AS MonthName
UNION ALL
SELECT MonthNum + 1, DATENAME(Month,DATEFROMPARTS(1, MonthNum + 1, 1)) AS MonthName
FROM months
WHERE MonthNum <= 11
),
years as (
SELECT YEAR(GETDATE())-1 AS Year
UNION ALL
SELECT Year + 1
FROM years
WHERE Year + 1 <= YEAR(GETDATE())
),
dates as (
SELECT Year, MonthNum, MonthName, DATEFROMPARTS(Year, MonthNum, 1) AS DateStart, DATEADD(MONTH, 1, DATEFROMPARTS(Year, MonthNum, 1)) AS DateEnd
FROM years
CROSS JOIN months
)
SELECT D.Year, D.MonthNum, D.MonthName, COUNT(ID) AS RequesCount
FROM dates D
LEFT JOIN YourTable A ON A.ProcessStartTime >= DateStart AND A.ProcessStartTime < DateEnd
WHERE DateStart < GETDATE()
GROUP BY D.Year, D.MonthNum, D.MonthName
ORDER BY Year, MonthNum
答案 2 :(得分:0)
尝试一下
SELECT months.month_name AS reqMonth, COUNT(ID) AS requestCount, YEAR(tn.processstarttime) AS reqYear
FROM A tn
RIGHT JOIN (VALUES ('january'),('february'),('march'),('april'),
('may'),('june'),('july'),('august'),('september'),
('october'),('november'),('december')) as months(month_name)
ON DATENAME(month,tn.processstarttime) = months.month_name
AND YEAR(tn.processstarttime) in (YEAR(DATEADD(MONTH, 0, GETDATE())),year(DATEADD(MONTH, -12, GETDATE())))
AND tn.processstarttime>DATEADD(MONTH, -12, GETDATE())
GROUP BY months.month_name,YEAR(tn.processstarttime)
order by months.month_name,YEAR(tn.processstarttime)
实际here