2014-06-05 44 views
0

我的應用程序在一天中的3個不同時間段中的每個時間段中保存至少需要記錄一次的日誌。所以理想情況下每天3個日誌,每個都有一個唯一的時間段ID。我需要編寫一份異常報告(MSSQL 2008),以顯示某一天某段時間內何時錯過。我有一個LogTimePeriods表,每個時間段包含3行。 Logs表包含LogTimePeriodID,因此我不需要執行任何邏輯來查看日誌屬於哪個時間段(這是通過應用程序完成的)。從右加入重複行

我知道我需要沿着右/左連接的行來嘗試匹配給定日期的每個日誌行的所有LogTimePeriodID。我似乎無法取得任何進展。任何幫助表示讚賞!謝謝閱讀。

SQL Fiddle

編輯:下面

日期所需的輸出| LogPeriodID
6/3 | 3
6/5 | 2
6/5 | 3

+0

那麼這將是該查詢的預期效果? – cy3er

+0

未完成日誌的日期和LogTimePeriodID列表。在我的小提琴6月3日,只有3個時間段中有2個完成,6月5日只有3箇中的1個(同一時間段完成兩次)。請參閱我的原始問題的編輯例如輸出。 – koolaide

回答

1

您的SQL小提琴設置爲使用MYSQL,而不是SQL Server 2008,所以我無法測試我對數據的答案:但是,根據我對您的要求的理解並假設您正在查詢SQL 2008數據庫,下面的例子應該爲你工作(對我的表變量的引用顯然將被你的實際表格所取代)。

DECLARE @StartDate DATE = '06/04/2014' 
DECLARE @EndDate DATE = GETDATE(); 
DECLARE @LogTimePeriod TABLE (LogTimePeriodID INT IDENTITY(1,1), TimePeriod VARCHAR(20)) 
INSERT INTO @LogTImePeriod (TimePeriod) SELECT '00:00 - 07:59' 
INSERT INTO @LogTImePeriod (TimePeriod) SELECT '08:00 - 15:59' 
INSERT INTO @LogTImePeriod (TimePeriod) SELECT '16:00 - 23:59' 


DECLARE @logs TABLE (LogDataID INT IDENTITY(1,1), LogDate DATE, SomeInformation VARCHAR(10), LogTimePeriodID INT) 
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'abc', '6/4/2014', 1 
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'def', '6/4/2014', 2 
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'ghi', '6/4/2014', 3 
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'abc', '6/5/2014', 1 
INSERT INTO @logs (SomeInformation, LogDate, LogTimePeriodID) SELECT 'def', '6/5/2014', 2; 


WITH dates AS (
    SELECT CAST(@StartDate AS DATETIME) 'date' 
    UNION ALL 
    SELECT DATEADD(dd, 1, t.date) 
     FROM dates t 
     WHERE DATEADD(dd, 1, t.date) <= @EndDate) 

SELECT ltp.LogTimePeriodID, ltp.TimePeriod, dates.date 
FROM 
    @LogTimePeriod ltp 
    INNER JOIN 
    dates ON 1=1 
    LEFT JOIN 
    @logs ld ON 
     ltp.LogTimePeriodID = ld.LogTimePeriodID AND 
     dates.date = ld.LogDate 
WHERE ld.LogDataID IS NULL 
OPTION (MAXRECURSION 1000) -- 0 is unlimited, 1000 limits to 1000 rows 
+0

是的!加入日期列表是我錯過的關鍵部分,這非常聰明。另外我很抱歉,我不知道SQL小提琴可以設置爲另一個數據庫引擎。謝謝你今天教我2件東西:) – koolaide

+0

非常歡迎。有人比我更聰明地提出了日期技巧列表,並且它在這裏運行良好,因爲您需要有效地創建具有所有可能組合的一組數據,然後才能確定哪些組合缺失。 – AHiggins

0

SQLServer 2008有EXCEPT關鍵字從第一個減去第二個記錄集。
在這種情況下,可以生成所有可能的日誌,並將其從日誌表中的日誌中移除,這將使日誌不在表中。

SELECT DISTINCT StartDateTime, StartTime, EndTime 
FROM Logs 
     CROSS JOIN LogTimePeriods 
EXCEPT 
SELECT StartDateTime, StartTime, EndTime 
FROM LogTimePeriods ltp 
     LEFT JOIN logs l ON l.LogTimePeriodID = ltp.LogTimePeriodID 
ORDER BY StartDateTime, StartTime 

SQLFiddle demo與您的數據轉換成2008年的SQLServer