我在Sql Server中有一个名为Lab_Analysis(ID int,Date Date,HeatNo decimal(18,3),Mn decimal(18,3),CaO decimal(18,3))
的表
现在,如果我想查看热量的总和,则不能输入Mn,CaO,则必须输入月份和年份。假设我给month = 2(平均2月),那么它应该显示该月每一天的HeatNo,Mn,CaO的总和,如果在任何一天都没有找到记录,则应该为0。为此,我这样做了: >
Declare @D table(Dt int,Val decimal(18,3))
insert into @D values(1,0),(2,0),(3,0),(4,0),(5,0),(6,0),(7,0),(8,0),(9,0),
(10,0),(11,0),(12,0),(13,0),(14,0),(15,0),(16,0),(17,0),(18,0),(19,0),
(20,0),(21,0),(22,0),(23,0),(24,0),(25,0),(26,0),(27,0),(28,0),(29,0),(30,0),(31,0)
SELECT D.Dt,ISNULL(SUM(L.HeatNo),0) HeatNo FROM @D D LEFT JOIN Lab_Analysis
L ON DATEPART(dd,L.Date)=D.Dt where DATEPART(MM,L.Date)=2 GROUP BY D.Dt
2月月份的记录仅在2月11日和13日插入。上面的查询仅显示行,但显示所有天数记录。如果在任何一天都找不到记录,则应显示0,而上述查询未显示。该如何解决?
答案 0 :(得分:2)
您在where子句DATEPART(MM,L.Date)= 2中使用L.Date,它将您的LEFT JOIN转换为INNER JOIN,您需要在ON子句中添加此条件
Declare @D table(Dt int,Val decimal(18,3))
insert into @D values(1,0),(2,0),(3,0),(4,0),(5,0),(6,0),(7,0),(8,0),(9,0),
(10,0),(11,0),(12,0),(13,0),(14,0),(15,0),(16,0),(17,0),(18,0),(19,0),
(20,0),(21,0),(22,0),(23,0),(24,0),(25,0),(26,0),(27,0),(28,0),(29,0),(30,0),(31,0)
SELECT D.Dt,ISNULL(SUM(L.HeatNo),0) HeatNo
FROM @D D
LEFT JOIN Lab_Analysis L ON
DATEPART(dd,L.Date)=D.Dt
AND DATEPART(MM,L.Date)=2
GROUP BY D.Dt
我建议您使用CTE创建日期,而不是为每个月创建一组值
DECLARE
@Year INT,
@Month INT,
@start DATE,
@end DATE
SET @Year = 2019
SET @Month = 2
SET @start = DATEFROMPARTS(@Year, @Month, 1)
SET @end = DATEADD(day, -1,DATEADD(month, 1, @start))
;WITH dates AS (
SELECT @start as theDate
UNION ALL
SELECT DATEADD(day, 1, theDate)
FROM dates
WHERE DATEADD(day, 1, theDate) <= @end
)
SELECT D.theDate,ISNULL(SUM(L.HeatNo),0) HeatNo
FROM dates D
LEFT JOIN Lab_Analysis L ON L.Date = theDate
GROUP BY theDate