我有一个简单的用户生产报告,其中跟踪每日配额。 sql为所有用户返回一周的数据,并且每天都会跟踪他们的总数。问题是,如果他们出去一天并且当天的产量为零,那么结果查询只会跳过该日并将其遗漏。即使桌子当天没有该人的参赛作品,我也希望返回。
table:
user date
andy 3/22/10
andy 3/22/10
andy 3/23/10
andy 3/24/10
andy 3/26/10
result:
andy
3/22/10 2
3/23/10 1
3/24/10 1
3/25/10 0
3/26/10 1
所以我的问题是如何让查询返回3/25/10日期,计数为0.
(我正在使用的当前查询):
SELECT A.USUS_ID as Processor, CONVERT(VARCHAR(10),A.CLST_STS_DTM,101) as Date,
COUNT(A.CLCL_ID) as DailyTotal
FROM CMC_CLST_STATUS A
WHERE A.CLST_STS_DTM >= (@Day) AND
DATEADD(d, 5, @Day) > A.CLST_STS_DTM
GROUP BY A.USUS_ID, CONVERT(VARCHAR(10),A.CLST_STS_DTM,101)
ORDER BY A.USUS_ID, CONVERT(VARCHAR(10),A.CLST_STS_DTM,101)
答案 0 :(得分:3)
你需要拥有该日期的数据,否则sql无法生成它。
解决此类问题的最常见方法是使用包含所有日期的日期表。然后你可以加入这个,这将允许你获得该日期的零条目。
您可以将此表永久保留在数据库中,也可以在运行查询时生成该表。哪种方式最好取决于使用情况等。
编辑:创建日期表的CTE方法
DECLARE @minDate DATETIME;
DECLARE @maxDate DATETIME;
SET @minDate = '2010-03-01 00:00:00.000';
SET @maxDate = '2010-03-10 00:00:00.000';
WITH DateRange ([date])
AS
(
SELECT @minDate
UNION ALL
SELECT
DATEADD(DAY, 1, [date])
FROM
DateRange
WHERE
DATEADD(DAY, 1, [date]) <= @maxDate
)
SELECT
*
FROM
DateRange
编辑2:我没有检查过,但它应该适用于您的数据库。
DECLARE @day DATETIME
SET @day = CAST(FLOOR(CAST(GETDATE() AS float)) AS DATETIME);
WITH DateRange ([Date])
AS
(
SELECT @day
UNION ALL
SELECT
DATEADD(DAY, 1, [Date])
FROM
DateRange
WHERE
DATEADD(DAY, 1, [Date]) <= DATEADD(DAY, 5, @day)
)
SELECT
A.USUS_ID as Processor,
DateRange.[Date] as Date,
COUNT(A.CLCL_ID) as DailyTotal
FROM
CMC_CLST_STATUS A
INNER JOIN
DateRange
ON
A.CLST_STS_DTM >= DateRange.[Date]
AND
A.CLST_STS_DTM < DATEADD(DAY, 1, DateRange.[Date])
GROUP BY
A.USUS_ID,
DateRange.[Date]
ORDER BY
A.USUS_ID,
DateRange.[Date]
答案 1 :(得分:1)
这是否来自存储过程?如果是这样,创建一个包含感兴趣日期的临时表,然后使用合适的连接和聚合来获取您要查找的数据...
答案 2 :(得分:0)
你几乎需要用你的表连接一个“表”(函数生成?不是在2005年,但我认为)包含开始日期和结束日期之间的所有日期。别无他法 - SQL不会显示那些不存在的东西。