当几个月有空数据时,如何包含使用Datepart的所有月份?
我有去年的销售和退款数据,但有些月份有NULL数据。如何包含这些月份,并有ROW_NUMBER增量?
SELECT
ROW_NUMBER() OVER (ORDER BY DATEPART(Year, SalesDate), DATEPART(MONTH, SalesDate)) AS 'RowNumber',
LEFT(datename(MONTH, SalesDate),3) AS 'Month',
DATEPART(Year, SalesDate) AS 'Year',
SUM(Refunds) 'Refunds',
COUNT(Sales),
SUM(Refunds) / COUNT(Sales) AS 'Percent Refunds'
FROM Sales_Table
WHERE SalesDate BETWEEN '10/01/2012' AND '12/31/2013'
GROUP BY DATEPART(Year, SalesDate), DATEPART(Month, SalesDate), DATENAME(month, SalesDate)
输出如下:
但是你可以看到2012年12月缺失了。我已经尝试过使用ISNULL和CASE WHEN NULL对计数和总和无效。
提前致谢!
答案 0 :(得分:0)
Kluge但快速修复
创建一个变量表@tblMonthYear,其中包含每个月组合的记录(代码省略)
所以@tblMonthYear有这三个字段
2000年1月1日
2020年12月12日
SELECT
ROW_NUMBER() OVER (ORDER BY DATEPART(Year, SalesDate),
DATEPART(MONTH, SalesDate)) AS 'RowNumber',
LEFT(datename(MONTH, SalesDate),3) AS 'Month',
DATEPART(Year, SalesDate) AS 'Year',
SUM(Refunds) 'Refunds',
COUNT(Sales),
SUM(Refunds) / COUNT(Sales) AS 'Percent Refunds'
FROM Sales_Table
LEFT JOIN @tblMonthYear
on @tblMonthYear.Month =LEFT(datename(MONTH, SalesDate),3)
and @tblMonthYear.Year = DATEPART(Year, SalesDate) AS 'Year'
WHERE SalesDate BETWEEN '10/01/2012' AND '12/31/2013'
答案 1 :(得分:0)
创建tmp表,如下所示:
create table #tmpTable (SalesDate dateTime,Refunds int,Sales int)
-- Populate
INSERT INTO #tmpTable VALUES ( '1/1/2013',0,0 )
INSERT INTO #tmpTable VALUES ( '2/1/2013',0,0 )
INSERT INTO #tmpTable VALUES ( '3/1/2013',0,0 )
INSERT INTO #tmpTable VALUES ( '4/1/2013',0,0 )
现在,调整你的代码
FROM ( select sales_date,sales,refunds from Sales_Table
union
select * from #tmpTable xx
left join Sales_table st on month(xx.sales_date)=month(st.sales_date) and
year(xx.sales_date)=year(st.sales_Date)
WHERE st.sales_date is null
) Sales_table
WHERE SalesDate BETWEEN '10/01/2012' AND '12/31/2013'
没有样本数据并且即时输入,但应该开始
答案 2 :(得分:0)
这是我为测试而生成的随机数据....
create table Sales_Table (
SalesDate date,
Sales decimal(18,2),
Refunds decimal(18,2))
insert into Sales_Table (SalesDate, Sales, Refunds)
values ('2013-01-15',1.99,0),
('2013-02-15',2.99,0),
('2013-03-15',3.99,0),
('2013-04-15',4.99,0),
('2013-05-15',5.99,0),
('2013-06-15',6.99,15),
('2013-07-15',7.99,0),
('2013-08-15',8.99,0),
('2013-09-15',8.99,0),
('2013-10-15',8.99,0),
('2013-11-15',8.99,0)
我添加了日历表...还使用了年份和月份函数而不是datepart(我发现它更具可读性)。
; WITH Calendar AS (
select m.number as [month], y.number as [year],
left(datename(month,convert(varchar,y.number)+'-'+convert(varchar,m.number)+'-'+'01'),3) as [monthname]
from master..spt_values y
cross join master..spt_values m
where y.type = 'p' and y.number between 2012 and 2013
and m.type = 'p' and m.number between 1 and 12
and y.number*100 + m.number between 201210 and 201312
), SalesData AS (
SELECT
Year(SalesDate) AS 'Year',
Month(SalesDate) AS 'Month',
SUM(Refunds) AS 'Refunds',
COUNT(Sales) AS 'SalesCount',
SUM(Refunds) / COUNT(Sales) AS 'Percent Refunds'
FROM Sales_Table
WHERE SalesDate BETWEEN '10/01/2012' AND '12/31/2013'
GROUP BY DATEPART(Year, SalesDate), DATEPART(Month, SalesDate), DATENAME(month, SalesDate)
)
select row_number() over (order by c.[year],c.[month]) as 'RowNumber',
c.[monthname] as 'Month',
c.[year] as 'Year',
coalesce(sd.Refunds,0) as 'Refunds',
coalesce(sd.SalesCount,0) as 'SalesCount',
coalesce(sd.[Percent Refunds],0) as 'Percent Refunds'
from Calendar c
left join SalesData sd
on c.[year] = sd.[year]
and c.[month] = sd.[month]
order by c.[year],c.[month]