2011-05-29 49 views
0

這個問題已經發布過,但是,正確的答案似乎並不奏效,所以我再次提出這個問題。在沒有任何東西的日子裏添加零點

如果沒有記錄,此代碼應該返回最後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

** **什麼數據庫 - ** **什麼??版本表什麼涉及到什麼是它們的結構(列和它們的數據類型)? – 2011-05-29 14:18:35

+0

microsoft sql server 2008,fnDateTable返回最後31天作爲日期(有一個鏈接到查詢)。數據類型爲TIMEDATE,並且查詢對於有數據的日期正確工作,但對於不工作的日期don.t – philbird 2011-05-29 14:19:10

+0

只有一個表usersAppLog,而fn返回日期列表 – philbird 2011-05-29 14:21:30

回答

1

由於您使用SQL Server 2008中,你可以嘗試下面的東西用Common Table Expression (CTE)OUTER APPLY所描述的一樣。

Common Table Expressions可用於執行遞歸函數。在這種情況下,CTE將初始日期作爲當前日期之前1個月的日期,然後遞歸循環加1天直到循環達到當前日期。因此,形成兩個給定日期之間的日期列表。使用該CTE輸出,我們可以使用OUTER APPLY來查找給定日期範圍內經過的持續時間的總和。

您也可以創建CTE作爲表值函數,並按照Table-valued函數一節所示使用它。下面提供的兩個選項都是相同的,它們將功能分開的方式略有不同。

截圖#示出了存儲在表dbo.UsersAppLog和截圖#顯示輸出的採樣數據。使用這兩種方法的輸出將是相同的,因爲下面給出的選項之間的唯一區別是它們中的一個將邏輯的一部分移至函數。 。

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:

Data

截圖#2:

Output

+0

非常感謝!這很好。我非常感謝你的幫助,特別是在這樣的細節。謝謝。 – philbird 2011-05-30 07:25:55