值更改后重新开始分区内的编号

Restarting numbering within partition once value change

我正在为非常简单的(我认为)主题而苦苦挣扎,我无法达到 运行。

示例数据:

|ready_signal|timestamp          |
|4           |2017-03-17 17:58:25|
|4           |2017-03-17 17:58:24|
|4           |2017-03-17 17:58:23|
|0           |2017-03-17 17:58:22|
|0           |2017-03-17 17:58:21|
|0           |2017-03-17 17:58:19|
|4           |2017-03-17 17:58:18|
|4           |2017-03-17 17:58:15|
|0           |2017-03-17 17:58:10|
|0           |2017-03-17 17:58:09|
|0           |2017-03-17 17:58:04|
|4           |2017-03-17 17:58:03|

现在我想要实现的是,在每个 ready_signal 更改中获得时间戳的最大值。 所以结果应该是这样的:

|ready_signal|timestamp          |
|4           |2017-03-17 17:58:25|
|0           |2017-03-17 17:58:22|
|4           |2017-03-17 17:58:18|
|0           |2017-03-17 17:58:10|
|4           |2017-03-17 17:58:09|

我尝试使用分区功能,使用 ROW_NUMBER 等,但没有成功。我无法对这些列的 none 进行分区。在 ready_signal 上进行分区将 return 只有两个值(并且在分区内使用 ORDER BY)。

我想,肯定有人遇到过同样的问题。就像,我需要一个唯一的分区号,但每次 ready_signal 值都会改变。

抱歉,没有发布示例代码。 这就是我正在试验的:

SELECT ready, 
    timestamp,
    ROW_NUMBER() OVER(PARTITION BY ready ORDER BY timestamp DESC) AS readyTime
FROM bubu
ORDER BY timestamp DESC

我也尝试获取一些最大值:

SELECT ready, 
    timestamp,
    ROW_NUMBER() OVER(PARTITION BY ready ORDER BY timestamp DESC) AS readyTime
FROM bubu
ORDER BY timestamp DESC

这很接近,但遇到了我对问题发表评论的问题 - 因为时间戳不是唯一的,所以可能会得到不同的结果集。在这种情况下,我 经常 得到 2017-03-17 17:58:09 的另一个 0 行,因为可以想象其中一个发生在 4.[=17= 之前]

无论如何,写这个的方法是你想要 select 那些 没有后继者 或后继者具有不同值的行 ready_state。一旦你像那样重述问题,代码实际上就是自己写的:

declare @t table (ready_signal int,timestamp datetime)
insert into @t(ready_signal,timestamp) values
(4,'2017-03-17T17:58:25'),
(4,'2017-03-17T17:58:24'),
(4,'2017-03-17T17:58:23'),
(0,'2017-03-17T17:58:22'),
(0,'2017-03-17T17:58:21'),
(0,'2017-03-17T17:58:19'),
(4,'2017-03-17T17:58:18'),
(4,'2017-03-17T17:58:15'),
(0,'2017-03-17T17:58:10'),
(0,'2017-03-17T17:58:09'),
(0,'2017-03-17T17:58:09'),
(4,'2017-03-17T17:58:09')

;With Numbered as (
    select ready_signal,timestamp,
        ROW_NUMBER() OVER (ORDER BY timestamp) as rn
    from @t
)
select
    t1.ready_signal,t1.timestamp
from
    Numbered t1
        left join
    Numbered t2
        on
            t1.rn = t2.rn - 1
where
    t2.rn is null or --No successor
    t2.ready_signal != t1.ready_signal --Successor different

结果:

ready_signal timestamp
------------ -----------------------
0            2017-03-17 17:58:09.000
4            2017-03-17 17:58:09.000
0            2017-03-17 17:58:10.000
4            2017-03-17 17:58:18.000
0            2017-03-17 17:58:22.000
4            2017-03-17 17:58:25.000

(如果结果集的顺序对您很重要,您可以添加显式 ORDER BY

尝试下面的查询,这将为您提供问题中描述的确切所需输出。

DECLARE @SAMPLEDATA TABLE(READYSIGNAL INT,TIMESTAMPP DATETIME)
INSERT INTO @SAMPLEDATA VALUES
(4,'2017-03-17 17:58:25'),
(4,'2017-03-17 17:58:24'),
(4,'2017-03-17 17:58:23'),
(0,'2017-03-17 17:58:22'),
(0,'2017-03-17 17:58:21'),
(0,'2017-03-17 17:58:19'),
(4,'2017-03-17 17:58:18'),
(4,'2017-03-17 17:58:15'),
(0,'2017-03-17 17:58:10'),
(0,'2017-03-17 17:58:09'),
(0,'2017-03-17 17:58:09'),
(4,'2017-03-17 17:58:09')
;WITH SAMPLEDATA
AS
(
SELECT *,1 COL FROM (SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 100))SNO,*
 FROM @SAMPLEDATA)T WHERE SNO=1
UNION ALL
SELECT T2.SNO,T2.READYSIGNAL,T2.TIMESTAMPP,
    CASE WHEN T1.READYSIGNAL=T2.READYSIGNAL THEN T1.COL ELSE T1.COL+1 END
        FROM SAMPLEDATA T1 JOIN (SELECT ROW_NUMBER()OVER(ORDER BY (SELECT     100))SNO,*
 FROM @SAMPLEDATA) T2 ON T1.SNO=T2.SNO-1
)
SELECT READYSIGNAL,TIMESTAMPP FROM
    (SELECT READYSIGNAL,MAX(TIMESTAMPP)TIMESTAMPP,MAX(SNO)SNO FROM     SAMPLEDATA     GROUP BY COL,READYSIGNAL)RESULT ORDER BY SNO 

输出

------------------------------------------
--READYSIGNAL   TIMESTAMPP
------------------------------------------
    4           2017-03-17 17:58:25.000
    0           2017-03-17 17:58:22.000
    4           2017-03-17 17:58:18.000
    0           2017-03-17 17:58:10.000
    4           2017-03-17 17:58:09.000
-----------------------------------------