Нулиране на номера на реда според промяната на записаните данни

Имам набор от данни, както следва

name  date  
x     2014-01-01
x     2014-01-02
y     2014-01-03
x     2014-01-04

и се опитвам да постигна този резултат

name  date           row_num
x     2014-01-01      1
x     2014-01-02      2
y     2014-01-03      1
x     2014-01-04      1

Опитах се да стартирам тази заявка

select name,
    date,
    row_number () over (partition by name order by date) as row_num
from myTBL

но за съжаление получавам този резултат

name  date           row_num
x     2014-01-01      1
x     2014-01-02      2
y     2014-01-03      1
x     2014-01-04      3

Моля помогнете.


person erezlale    schedule 28.12.2014    source източник
comment
коя база данни - sql сървър, oracle и т.н.? каква е логиката за присвояване на номера на реда по този начин? какво се опитваш да направиш в крайна сметка?   -  person Erran Morad    schedule 29.12.2014
comment
Вашето partition by изявление казва, че дяловете са базирани единствено на name. Резултатът, който сте получили, е резултатът, който поискахте. Резултатът, който изглежда искате, е дяловете да се нулират всеки път, когато изпълнение на name се промени. Не мисля, че можете да направите това с проста функция за прозорец. Ще ви трябват едно или две нива на подзаявка.   -  person Ross Presser    schedule 29.12.2014
comment
За бъдещите питащи, това попада в класа проблеми, известни като gaps-and-islands.   -  person Clockwork-Muse    schedule 29.12.2014


Отговори (1)


Трябва да идентифицирате групите от names, които се срещат заедно. Можете да направите това с разлика в номерата на редовете. След това използвайте grp за разделяне на row_number():

select name, date,
       row_number() over (partition by name, grp order by date) as row_num
from (select t.*,
             (row_number() over (order by date) -
              row_number() over (partition by name order by date)
             ) as grp
      from myTBL t
     ) t

За вашите примерни данни:

name  date         1st row_number   2nd      Grp
x     2014-01-01         1           1        0
x     2014-01-02         2           2        0
y     2014-01-03         3           1        2
x     2014-01-04         4           3        1

Това трябва да ви даде представа как работи.

person Gordon Linoff    schedule 28.12.2014
comment
Това е много полезно решение, защото трябва да работи на всяка база данни, която поддържа ROW_NUMBER() (което е повечето от тях) +1. - person Tim Biegeleisen; 30.03.2017
comment
благодаря наистина, това беше полезно и в моята ситуация - person ZSchneidi; 16.09.2020