0

我的应用程序保存需要在一天中的 3 个不同时间段中的每个时间段中至少记录一次的日志。所以理想情况下每天 3 条日志,每条日志都有一个唯一的时间段 ID。我需要编写一个异常报告(MSSQL 2008),它会显示任何给定日期错过某个时间段的时间。我有一个 LogTimePeriods 表,其中包含每个时间段的 3 行。Logs 表包含 LogTimePeriodID,因此我不需要执行任何逻辑来查看日志所属的时间段(通过应用程序完成)。

我知道我需要一些类似于右/左连接的东西来尝试匹配给定日期的每个 Log 行的所有 LogTimePeriodID。我似乎无法取得任何进展。任何帮助表示赞赏!谢谢阅读。

SQL小提琴

编辑:下面的所需输出

日期 | LogPeriodID
6/3 | 3
6/5 | 2
6/5 | 3

4

2 回答 2

1

您的 SQL Fiddle 设置为使用 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 
于 2014-06-05T15:29:23.977 回答
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将您的数据转换为 SQLServer 2008

于 2014-06-05T16:00:25.200 回答