Sql server SQL Server正在比较后续行中是否存在重复项
我正在尝试编写一个SQL Server查询,但运气不好,我想知道是否有人对如何实现我的查询有任何想法 我想做的是: 我有一个表,其中有几个列,这些列命名了我正在处理的TaskID、StatusCode和Timestamp。现在,这个表只保存了我们一个系统的任务,这些任务整天都在运行,当某个系统运行时,它会根据该任务的状态获取时间戳和状态码 有时,任务表将使用新的时间戳进行更新,但自上次更新任务以来,状态代码不会发生更改,因此对于给定任务的两行或多行,状态代码可以相同。当我说连续行时,我指的是时间戳 因此,示例任务88在状态代码2处可能有20行,之后状态代码将更改为其他代码 现在我想做的是从这个表中检索所有任务、状态码和时间戳的列表,但如果一个任务有多个连续的行,且状态码相同,我只想取时间戳最低的第一行,忽略该行的其余部分,直到该任务的状态代码将更改 为了简化这个例子,您可以假设我有一个taskid,我正在筛选它,所以我只查看一个任务 有没有人对我如何做到这一点有什么想法,或者我可以读一些东西来帮助我 谢谢 Irfan.类似于Sql server SQL Server正在比较后续行中是否存在重复项,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,我正在尝试编写一个SQL Server查询,但运气不好,我想知道是否有人对如何实现我的查询有任何想法 我想做的是: 我有一个表,其中有几个列,这些列命名了我正在处理的TaskID、StatusCode和Timestamp。现在,这个表只保存了我们一个系统的任务,这些任务整天都在运行,当某个系统运行时,它会根据该任务的状态获取时间戳和状态码 有时,任务表将使用新的时间戳进行更新,但自上次更新任务以来,状态代码不会发生更改,因此对于给定任务的两行或多行,状态代码可以相同。当我说连续行时,我指的是时间
select TaskID,StatusCode,Min(TimeStamp)
from table
group by TaskID,StatusCode
order by 1,2
请注意,如果状态码可以重复,您将需要一个额外的字段,但希望这可以为您指明正确的方向…类似于以下内容的内容将为您指明正确的方向
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
以下是获得您想要的东西的两种方法:
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
或
这两种方法都依赖于状态\u时间戳值没有精确匹配。对于给定的任务id,两行不能具有相同的精确状态\u时间戳。我忘了提到我使用的是SQL SERVER 2005。您尝试执行的操作对我来说听起来非常程序化-因此,也许您最好使用C之类的工具,而不是尝试执行让T-SQL去做。嘿,Marc,你知道我是这么想的,但我之所以这么做是为了减少SQL的负载。对于某些任务,如果没有这种逻辑,由于重复的状态代码行的数量太多,我可以得到几千行。如果我可以根据状态代码将结果集减少为只包含不同的行,这将大大加快速度。谢谢你的回复。这真的很接近,但问题在于表中我只想忽略任务给定状态的剩余行,如果其后续连续行具有相同的状态代码。一个任务可以转到状态代码2,然后转到3,然后再回到2,这些都是我想显示的有效行,因为状态代码2不是连续发生的。我想您的查询将为我提供该任务给定状态的最小时间戳。这就是为什么我的查询由于连续行问题而如此奇怪。谢谢Jay,这是一个非常智能的查询,但这与Sparky上面的查询有相同的问题,它将statuscode和taskid分组在一起,并且每个状态代码只返回一行。例如,如果我将行UNION SELECT 1,2,'2009-12-0219:15';已将此状态代码插入到查询中,但此状态代码与其他状态代码不连续,因此应显示。上面的查询是将这一行与其他行组合在一起。我想写一个光标,在那里我可以跟踪上一个状态码,如果它与当前状态码相同,我就不进入我的临时表,如果它不同,我就进入我的临时表。最后,我将有一个临时表,其中包含我想要的数据。由于光标的存在,查询速度较慢。这一切都取决于如果我这样做的话,光标对几百行执行此操作需要多长时间?谢谢Tom,我使用了第二个查询和一些mod来实现我的目的,但它做到了,而且非常快。非常感谢你的帮助。
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