此问题之前已经发布,但是,正确的答案似乎不起作用,所以我再次问它。
如果没有记录,此代码应返回最后31天,为零;
SELECT dates.Date as Dates, isnull(Sum(ElapsedTimeSeconds),0) as ElapsedSeconds
FROM
[fnDateTable] (dateadd("m",-1,CONVERT(VARCHAR(10),GETDATE(),111)),CONVERT(VARCHAR(10),GETDATE(),111),'day') dates
LEFT JOIN UsersApplog on dates.date = UsersAppLog.LoggedDate
group by Dates.Date
在这里查看[fnDateTable]; fnDateTable
我得到的只是拥有数据的行。很烦人。
感谢您提供任何帮助。我确信这是一个简单的解决方案,但它超出了我的范围。
这是一些输出,其中有来自userapplog的数据;
Dates ElapsedSeconds
2011-05-17 00:00:00.000 5854
2011-05-18 00:00:00.000 5864
2011-05-21 00:00:00.000 4758
2011-05-22 00:00:00.000 8434
2011-05-23 00:00:00.000 2162
2011-05-25 00:00:00.000 491
2011-05-26 00:00:00.000 260
2011-05-28 00:00:00.000 216
如果我跑;
SELECT dates.Date as Dates
FROM
[fnDateTable] (dateadd("m",- 1,CONVERT(VARCHAR(10),GETDATE(),111)),CONVERT(VARCHAR(10),GETDATE(),111),'day') dates
我得到了
Dates
2011-04-29 00:00:00.000
2011-04-30 00:00:00.000
2011-05-01 00:00:00.000
2011-05-02 00:00:00.000
2011-05-03 00:00:00.000
2011-05-04 00:00:00.000
2011-05-05 00:00:00.000
.
.
答案 0 :(得分:1)
由于您使用的是SQL Server 2008,因此可以尝试使用Common Table Expression (CTE)
和OUTER APPLY
进行如下所述的操作。
Common Table Expressions
可用于执行递归函数。在这种情况下,CTE将初始日期作为当前日期之前1个月的日期,然后通过添加1天递归循环,直到循环到达当前日期。因此,形成两个给定日期之间的日期列表。使用该CTE输出,我们可以使用OUTER APPLY
来查找给定日期范围的经过持续时间的总和。
您还可以将CTE创建为表值函数,并使用它,如表值函数一节所示。下面提供的两个选项都是相同的,它们将功能略有不同。
屏幕截图# 1 显示存储在表dbo.UsersAppLog中的示例数据,屏幕截图# 2 显示输出。使用两种方法的输出都是相同的,因为下面给出的选项之间的唯一区别是其中一个将逻辑的一部分移动到一个函数。
<强> Option #1
强>
不使用表值函数的所需输出:
DECLARE @BeginDate DATETIME;
DECLARE @EndDate DATETIME;
SET @BeginDate = DATEADD(MONTH, -1, GETDATE());
SET @EndDate = GETDATE();
WITH CTE(DateRange) AS
(
SELECT @BeginDate AS DateRange
UNION ALL
SELECT DATEADD(DAY, 1, DateRange)
FROM CTE
WHERE DATEADD(DAY, 1, DateRange) <= @EndDate
)
SELECT DATEADD(DAY, 0, DATEDIFF(DAY, 0, CTE.DateRange)) AS DateRange
, COALESCE(UAL.ElapsedDuration, 0) AS ElapsedDuration
FROM CTE
OUTER APPLY (
SELECT SUM(ElapsedSeconds) ElapsedDuration
FROM dbo.UsersAppLog UAL
WHERE DATEDIFF(DAY, UAL.LoggedDate, CTE.DateRange) = 0
) UAL;
<强> Option #2
强>
为表值函数创建脚本:
CREATE FUNCTION [dbo].[fntDateRange]
(
@BeginDate DATETIME
, @EndDate DATETIME
)
RETURNS TABLE
AS
RETURN
(
WITH CTE(DateRange) AS
(
SELECT @BeginDate AS DateRange
UNION ALL
SELECT DATEADD(DAY, 1, DateRange)
FROM CTE
WHERE DATEADD(DAY, 1, DateRange) <= @EndDate
)
SELECT DATEADD(DAY, 0, DATEDIFF(DAY, 0, CTE.DateRange)) AS DateRange
FROM CTE
)
GO
使用表值函数的期望输出:
SELECT RNG.DateRange
, COALESCE(UAL.ElapsedDuration, 0) AS ElapsedDuration
FROM dbo.fntDateRange(DATEADD(MONTH, -1, GETDATE()), GETDATE()) RNG
OUTER APPLY (
SELECT SUM(ElapsedSeconds) ElapsedDuration
FROM dbo.UsersAppLog UAL
WHERE DATEDIFF(DAY, UAL.LoggedDate, RNG.DateRange) = 0
) UAL;
希望有所帮助。
屏幕截图#1:
屏幕截图#2: