开发者

add zero for the days with nothing in them

开发者 https://www.devze.com 2023-03-08 21:38 出处:网络
This question has already been posted before, however, the correct answer doesn\'t seem to work, so I\'m asking it again.

This question has already been posted before, however, the correct answer doesn't seem to work, so I'm asking it again.

This code, should return the last 31 days with zero if there are no records;

   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

See the [fnDateTable] here; fnDateTable

what I get back is JUST the rows which have data. Very a开发者_开发问答nnoying.

Thanks for any help you can give. I'm sure it's a simple solve, but it's beyond me.

This is some output where there is data from the 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

If I run;

 SELECT dates.Date as Dates
   FROM 
   [fnDateTable] (dateadd("m",-   1,CONVERT(VARCHAR(10),GETDATE(),111)),CONVERT(VARCHAR(10),GETDATE(),111),'day') dates 

I get

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
.
.


Since you are using SQL Server 2008, you could try something like as described below using Common Table Expression (CTE) and OUTER APPLY.

Common Table Expressions can be used to perform recursive functions. In this case, the CTE takes the initial date as the date 1 month prior from current date and then recursively loops by adding 1 day until the loop reaches the current date. Hence, forming the list of dates between two given dates. Using that CTE output, we can use OUTER APPLY to find the sum of elapsed duration for a given date range.

You can also create the CTE as table-valued function and use it as shown under section Table-valued function. Both options provided below are same and they are separating the functionalities slightly differently.

Screenshot #1 shows the sample data stored in the table dbo.UsersAppLog and the screenshot #2 displays the output. The output will be same using both approaches because the only difference between below given options is one of them have part of the logic moved to a function. .

Option #1

Desired output without using table-valued function:

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 script for Table-Valued function: .

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

Desired output using the table-valued function: .

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;

Hope that helps.

Screenshot #1:

add zero for the days with nothing in them

Screenshot #2:

add zero for the days with nothing in them

0

精彩评论

暂无评论...
验证码 换一张
取 消