Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server正在比较后续行中是否存在重复项_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

Sql server SQL Server正在比较后续行中是否存在重复项

Sql server SQL Server正在比较后续行中是否存在重复项,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,我正在尝试编写一个SQL Server查询,但运气不好,我想知道是否有人对如何实现我的查询有任何想法 我想做的是: 我有一个表,其中有几个列,这些列命名了我正在处理的TaskID、StatusCode和Timestamp。现在,这个表只保存了我们一个系统的任务,这些任务整天都在运行,当某个系统运行时,它会根据该任务的状态获取时间戳和状态码 有时,任务表将使用新的时间戳进行更新,但自上次更新任务以来,状态代码不会发生更改,因此对于给定任务的两行或多行,状态代码可以相同。当我说连续行时,我指的是时间

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

我想做的是:

我有一个表,其中有几个列,这些列命名了我正在处理的TaskID、StatusCode和Timestamp。现在,这个表只保存了我们一个系统的任务,这些任务整天都在运行,当某个系统运行时,它会根据该任务的状态获取时间戳和状态码

有时,任务表将使用新的时间戳进行更新,但自上次更新任务以来,状态代码不会发生更改,因此对于给定任务的两行或多行,状态代码可以相同。当我说连续行时,我指的是时间戳

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

现在我想做的是从这个表中检索所有任务、状态码和时间戳的列表,但如果一个任务有多个连续的行,且状态码相同,我只想取时间戳最低的第一行,忽略该行的其余部分,直到该任务的状态代码将更改

为了简化这个例子,您可以假设我有一个taskid,我正在筛选它,所以我只查看一个任务

有没有人对我如何做到这一点有什么想法,或者我可以读一些东西来帮助我

谢谢 Irfan.

类似于

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