Sql 将序号指定给具有重复值的行

Sql 将序号指定给具有重复值的行,sql,sql-server,sql-server-2008,window-functions,Sql,Sql Server,Sql Server 2008,Window Functions,我有下表: ITEM DATE VALUE ---------------------- ITEM1 2016-05-04 1 ITEM1 2016-05-05 3 ITEM1 2016-05-06 3 ITEM1 2016-05-09 3 ITEM1 2016-05-04 4 ITEM2 2016-05-10 1 ITEM2 2016-05-05 2 ITEM2 2016-05-06 3 ITEM2 2016-05-09

我有下表:

ITEM    DATE        VALUE
----------------------
ITEM1   2016-05-04  1
ITEM1   2016-05-05  3
ITEM1   2016-05-06  3
ITEM1   2016-05-09  3
ITEM1   2016-05-04  4
ITEM2   2016-05-10  1
ITEM2   2016-05-05  2
ITEM2   2016-05-06  3
ITEM2   2016-05-09  1
ITEM2   2016-05-10  1
我想找出,每一项,有多少项在时间上是相同的(平的):

我最初的想法是:

select 
    *,
    rank()-1 over (partition by ITEM,VALUE order by DATE) as NUM_FLAT_ENTRYPOINTS 
from my_table
但是,这不起作用,因为第2项将2016-05-04、2016-05-09和2016-05-10划分在一起,最后一行的NUM_FLAT_入口点显示为2而不是1

我正在使用Microsoft SQL Server 2008

有什么想法吗

编辑:

在Oracle(以及其他可能的SQL服务器)中,我似乎可以这样做

select
    count(VALUE)-1 over (partition by ITEM,VALUE order by DATE) as NUM_FLAT_ENTRYPOINTS 
from my_table

但据我所知,这种语法在SQLServer2008中不起作用。有没有办法解决这个问题?

假设对我在评论中建议的样本数据进行了更正,这似乎符合要求:

declare @t table (ITEM char(5), Date date, Value tinyint)
insert into @t(ITEM,DATE,VALUE) values
('ITEM1','20160504',1),
('ITEM1','20160505',3),
('ITEM1','20160506',3),
('ITEM1','20160509',3),
('ITEM1','20160510',4),
('ITEM2','20160504',1),
('ITEM2','20160505',2),
('ITEM2','20160506',3),
('ITEM2','20160509',1),
('ITEM2','20160510',1)

;With Ordered as (
    select
        Item,
        Date,
        Value,
        ROW_NUMBER() OVER (PARTITION BY Item ORDER BY Date) as rn
    from @t
)
select
    *,
    COALESCE(rn -
        (select MAX(o2.rn) from Ordered o2
        where o2.ITEM = o.ITEM and
            o2.rn < o.rn and
            o2.Value != o.Value) - 1
    , o.rn - 1) as NUM_FLAT_ENTRYPOINTS
from
    Ordered o

它看起来像是缺口和岛屿的变体

样本数据

DECLARE @T TABLE (ITEM varchar(50), dt date, VALUE int);
INSERT INTO @T(ITEM, dt, VALUE) VALUES
('ITEM1', '2016-05-04', 1),
('ITEM1', '2016-05-05', 3),
('ITEM1', '2016-05-06', 3),
('ITEM1', '2016-05-09', 3),
('ITEM1', '2016-05-10', 4),
('ITEM2', '2016-05-04', 1),
('ITEM2', '2016-05-05', 2),
('ITEM2', '2016-05-06', 3),
('ITEM2', '2016-05-09', 1),
('ITEM2', '2016-05-10', 1);
查询

WITH
CTE
AS
(
    SELECT
        ITEM
        ,dt
        ,VALUE
        ,ROW_NUMBER() OVER (PARTITION BY ITEM ORDER BY dt) AS rn1
        ,ROW_NUMBER() OVER (PARTITION BY ITEM, VALUE ORDER BY dt) AS rn2
    FROM @T
)
SELECT
    ITEM
    ,dt
    ,VALUE
    ,rn1-rn2 AS rnDiff
    ,ROW_NUMBER() OVER 
        (PARTITION BY ITEM, VALUE, rn1-rn2 ORDER BY dt) - 1 AS NUM_FLAT_ENTRYPOINTS
FROM CTE
ORDER BY ITEM, dt;
结果

+-------+------------+-------+--------+----------------------+
| ITEM  |     dt     | VALUE | rnDiff | NUM_FLAT_ENTRYPOINTS |
+-------+------------+-------+--------+----------------------+
| ITEM1 | 2016-05-04 |     1 |      0 |                    0 |
| ITEM1 | 2016-05-05 |     3 |      1 |                    0 |
| ITEM1 | 2016-05-06 |     3 |      1 |                    1 |
| ITEM1 | 2016-05-09 |     3 |      1 |                    2 |
| ITEM1 | 2016-05-10 |     4 |      4 |                    0 |
| ITEM2 | 2016-05-04 |     1 |      0 |                    0 |
| ITEM2 | 2016-05-05 |     2 |      1 |                    0 |
| ITEM2 | 2016-05-06 |     3 |      2 |                    0 |
| ITEM2 | 2016-05-09 |     1 |      2 |                    0 |
| ITEM2 | 2016-05-10 |     1 |      2 |                    1 |
+-------+------------+-------+--------+----------------------+
试试这个:

SELECT ITEM, [DATE], VALUE,
       ROW_NUMBER() OVER (PARTITION BY ITEM, VALUE, grp 
                          ORDER BY [DATE]) - 1 AS NUM_FLAT_ENTRYPOINTS 
FROM (
SELECT ITEM, [DATE], VALUE,
       ROW_NUMBER() OVER (PARTITION BY ITEM ORDER BY [DATE]) - 
       ROW_NUMBER() OVER (PARTITION BY ITEM, VALUE ORDER BY [DATE]) AS grp
FROM mytable) AS t

我假设在您的示例数据中,每个项目的最后一行应该是
2016-05-10
,而不是
2016-05-04
,并且
DATE
定义了行的评估顺序?否则,请详细说明这里的规则……您是正确的,先生,修正了!
+-------+------------+-------+--------+----------------------+
| ITEM  |     dt     | VALUE | rnDiff | NUM_FLAT_ENTRYPOINTS |
+-------+------------+-------+--------+----------------------+
| ITEM1 | 2016-05-04 |     1 |      0 |                    0 |
| ITEM1 | 2016-05-05 |     3 |      1 |                    0 |
| ITEM1 | 2016-05-06 |     3 |      1 |                    1 |
| ITEM1 | 2016-05-09 |     3 |      1 |                    2 |
| ITEM1 | 2016-05-10 |     4 |      4 |                    0 |
| ITEM2 | 2016-05-04 |     1 |      0 |                    0 |
| ITEM2 | 2016-05-05 |     2 |      1 |                    0 |
| ITEM2 | 2016-05-06 |     3 |      2 |                    0 |
| ITEM2 | 2016-05-09 |     1 |      2 |                    0 |
| ITEM2 | 2016-05-10 |     1 |      2 |                    1 |
+-------+------------+-------+--------+----------------------+
SELECT ITEM, [DATE], VALUE,
       ROW_NUMBER() OVER (PARTITION BY ITEM, VALUE, grp 
                          ORDER BY [DATE]) - 1 AS NUM_FLAT_ENTRYPOINTS 
FROM (
SELECT ITEM, [DATE], VALUE,
       ROW_NUMBER() OVER (PARTITION BY ITEM ORDER BY [DATE]) - 
       ROW_NUMBER() OVER (PARTITION BY ITEM, VALUE ORDER BY [DATE]) AS grp
FROM mytable) AS t