SQL Server比较重复的后续行

时间:2009-12-07 17:36:52

标签: sql-server sql-server-2005 tsql

我正在尝试编写一个SQL Server查询,但没有运气,并且想知道是否有人对如何实现我的查询有任何想法。

我正在尝试做什么:

我有一个包含多个列的表,这些列命名我正在处理TaskID,StatusCode,Timestamp的那些列。现在,这个表只保存我们的一个系统的任务,这些系统在一天中运行,当运行时,它会获得时间戳和状态代码,具体取决于该任务的状态。

有时会发生的事情是任务表将使用新的时间戳更新,但statusCode自上次更新任务后不会发生更改,因此对于给定任务的两个或多个连续行,statusCode可以是相同的。当我说连续行时,我的意思是关于时间戳。

因此,示例任务88可以在statusCode 2处有20行,之后状态代码将更改为其他内容。

现在我正在尝试做的就是从这个表中检索所有任务和状态代码以及时间戳的列表,但是在我有一个以上连续行的任务的情况下相同的状态代码我只想获取具有最低时间戳的第一行,并忽略该行的其余部分,直到该任务的状态代码发生变化。

为了简化这种情况你可以假设我有一个我正在过滤的taskid所以我只是在看一个单一的任务。

有没有人对我如何做到这一点有任何想法,或者也许是我可能会阅读以帮助我的事情?

由于 伊尔凡。

3 个答案:

答案 0 :(得分:2)

这有几种方法可以获得你想要的东西:

SELECT
     T1.task_id,
     T1.status_code,
     T1.status_timestamp
FROM
     My_Table T1
LEFT OUTER JOIN My_Table T2 ON
     T2.task_id = T1.task_id AND
     T2.status_timestamp < T1.status_timestamp
LEFT OUTER JOIN My_Table T3 ON
     T3.task_id = T1.task_id AND
     T3.status_timestamp < T1.status_timestamp AND
     T3.status_timestamp > T2.status_timestamp
WHERE
     T3.task_id IS NULL AND
     (T2.status_code IS NULL OR T2.status_code <> T1.status_code)
ORDER BY
     T1.status_timestamp

SELECT
     T1.task_id,
     T1.status_code,
     T1.status_timestamp
FROM
     My_Table T1
LEFT OUTER JOIN My_Table T2 ON
     T2.task_id = T1.task_id AND
     T2.status_timestamp = (
          SELECT
               MAX(status_timestamp)
          FROM
               My_Table T3
          WHERE
               T3.task_id = T1.task_id AND
               T3.status_timestamp < T1.status_timestamp)
WHERE
     (T2.status_code IS NULL OR T2.status_code <> T1.status_code)
ORDER BY
     T1.status_timestamp

两种方法都依赖于status_timestamp值没有完全匹配(对于给定的task_id,两行不能具有完全相同的status_timestamp。)

答案 1 :(得分:1)

这样的东西
select TaskID,StatusCode,Min(TimeStamp)
from table
group by TaskID,StatusCode
order by 1,2

请注意,状态代码可以复制,您需要一个额外的字段,但希望这可以指向正确的方向......

答案 2 :(得分:0)

以下内容应该让你朝着正确的方向前进......

CREATE TABLE #T
(
    TaskId INT
    ,StatusCode INT
    ,StatusTimeStamp DATETIME
)

INSERT INTO #T
SELECT 1, 1, '2009-12-01 14:20'
UNION SELECT 1, 2, '2009-12-01 16:20'
UNION SELECT 1, 2, '2009-12-02 09:15'
UNION SELECT 1, 2, '2009-12-02 12:15'
UNION SELECT 1, 3, '2009-12-02 18:15'

;WITH CTE AS
(
SELECT TaskId
        ,StatusCode
        ,StatusTimeStamp
        ,ROW_NUMBER() OVER (PARTITION BY TaskId, StatusCode ORDER BY TaskId, StatusTimeStamp DESC)  AS RNUM
FROM  #T
)
SELECT TaskId
        ,StatusCode
        ,StatusTimeStamp
FROM CTE
WHERE RNUM = 1

DROP TABLE #T