SQL Server:最大日期和内部联接

时间:2012-09-26 01:51:51

标签: sql database windows sql-server-2008 tsql

我有两个表,一个是任务列表。另一个包含这些任务的历史值。

我需要为每个检查生成最新事件(及其描述)的列表,只要其Date_Executed小于当前日期时间减去Timeframe({{1必须完成任务中的小时数,格式化以便在TimeFrame中使用。但只有他们有DATEADD

表:检查

active = 1

表:事件

Check_id  description  TimeFrame active
1         Task One     -24       0
2         Task Two     -24       0
3         Task Forty   -48       1
4         Task Somehin -128      1

到目前为止,我所拥有的最佳解决方案是:

Event_id  Check_id   Comment     Date_Executed             User_Executed
1         1          NULL        2012-09-18 16:10:44.917   admin
2         1          NULL        2012-09-25 11:39:01.000   jeff
3         4          Failed      2012-09-25 13:20:09.930   steve
4         4          Half failed 2012-09-25 13:05:09.953   marsha
5         2          NULL        2012-09-25 14:02:24.000   marsha
6         3          NULL        2012-09-18 16:10:55.023   marsha

SELECT 
    a.[Date_Executed]
    a.[Check_id], 
    a.[Comments],
    b.[frequency], 
    b.[Check_id],
    b.[description]     
FROM 
    [checksdb].[dbo].events as a, 
    [checksdb].[dbo].checks as b
where 
    b.active = 1
    and a.[Date_Executed] < = dateadd(HOUR,b.[frequency],GETDATE())
    and a.Check_id = b.Check_id
order by Check_id, priority

这些都没有让我得到我需要的东西,我真的可以使用一些帮助。

1 个答案:

答案 0 :(得分:8)

由于您SQL Server支持Common Table ExpressionWindow Function。试试这个,

WITH latestEvents
AS
(
  SELECT  Event_id, Check_id, [Comment], Date_Executed, User_Executed,
          ROW_NUMBER() OVER(PARTITION BY Check_ID ORDER BY DATE_Executed DESC) 
              AS RowNum
  FROM    events
)
SELECT  a.[Check_id], a.[description],
        b.[Date_Executed], b.[Comment]
FROM    checks a
        INNER JOIN latestEvents b
            on a.check_ID = b.check_ID
WHERE   b.RowNum = 1 AND
        a.active = 1
        -- other conditions here

SQLFiddle Demo

以上查询仅适用于支持Window Functions的RDBMS。或者,使用下面适用于大多数RDBMS的查询

SELECT  a.Check_id, a.description,
        c.Date_Executed, c.Comment
FROM    checks a
        INNER JOIN
        (
          SELECT check_id, MAX(Date_Executed) maxExecuted
          FROM   events
          GROUP BY check_ID
        ) b ON a.check_ID = b.check_ID
        INNER JOIN events c
          ON c.check_ID = b.check_ID AND
             c.date_executed = b.maxExecuted
WHERE   a.active = 1

SQLFiddle Demo