Отсутствующие пробелы в повторяющихся сериях внутри группы - PullRequest
0 голосов
/ 02 декабря 2011

У нас есть таблица со следующими данными

Id,ItemId,SeqNumber;DateTimeTrx
1,100,254,2011-12-01 09:00:00
2,100,1,2011-12-01 09:10:00
3,200,7,2011-12-02 11:00:00
4,200,5,2011-12-02 10:00:00
5,100,255,2011-12-01 09:05:00
6,200,3,2011-12-02 09:00:00
7,300,0,2011-12-03 10:00:00
8,300,255,2011-12-03 11:00:00
9,300,1,2011-12-03 10:30:00

Идентификатор - это столбец идентификаторов. Последовательность для ItemId начинается с 0 и продолжается до 255, а затем сбрасывается до 0. Вся эта информация хранится в таблице с именем Item. Порядок порядкового номера определяется DateTimeTrx, но такие данные могут в любое время вводиться в систему. Ожидаемый результат показан ниже -

ItemId,PrevorNext,SeqNumber,DateTimeTrx,MissingNumber
100,Previous,255,2011-12-01 09:05:00,0
100,Next,1,2011-12-01 09:10:00,0
200,Previous,3,2011-12-02 09:00:00,4
200,Next,5,2011-12-02 10:00:00,4
200,Previous,5,2011-12-02 10:00:00,6
200,Next,7,2011-12-02 11:00:00,6
300,Previous,1,2011-12-03 10:30:00,2
300,Next,255,2011-12-03 16:30:00,2

Нам нужно получить эти строки одну до и одну после пропущенной последовательности. В приведенном выше примере для ItemId 300 - сначала вводится запись с последовательностью 1 (2011-12-03 10:30:00), а затем 255 (2011-12-03 16:30:00), поэтому здесь отсутствует число 2. Таким образом, 1 является предыдущим, 255 - следующим, а 2 - первым пропущенным числом. Что касается ItemId 100, сначала вводится запись с последовательностью 255 (2011-12-02 09:05:00), а затем 1 (2011-12-02 09:10:00), следовательно, 255 - предыдущая, а затем 1, следовательно 0 - это первое пропущенное число.

В приведенном выше ожидаемом результате столбец MissingNumber является первым отсутствующим номером только для иллюстрации примера.

У нас не будет случая, когда у нас будет полный сброс серии за один раз, т. Е. Это может быть либо сокращение серии от 255 до 0, как для itemid 100, либо от 0 до 255, как в ItemId 300. Следовательно, нам нужно идентифицировать отсутствующую последовательность в возрастающем порядке (0,1, ... 255) или в убывающем порядке (254,254,0,2) и т. д.

Как мы можем сделать это в t-sql?

1 Ответ

1 голос
/ 02 декабря 2011

Может работать так:

;WITH b AS (
   SELECT *
         ,row_number() OVER (ORDER BY ItemId, DateTimeTrx, SeqNumber) AS rn
   FROM   tbl
   ), x AS (
   SELECT
       b.Id
      ,b.ItemId    AS prev_Itm
      ,b.SeqNumber AS prev_Seq
      ,c.ItemId    AS next_Itm
      ,c.SeqNumber AS next_Seq
   FROM   b
   JOIN   b c ON c.rn = b.rn + 1                -- next row
   WHERE  c.ItemId = b.ItemId                   -- only with same ItemId
   AND    c.SeqNumber <> (b.SeqNumber + 1)%256  -- Seq cycles modulo 256
   )
SELECT Id, prev_Itm, 'Previous' AS PrevNext, prev_Seq
FROM   x
UNION  ALL
SELECT Id, next_Itm ,'Next', next_Seq
FROM   x
ORDER  BY Id, PrevNext DESC

Дает точно запрошенный результат.
См. полную рабочую демонстрацию по данным. SE .

В этом решении учитывается пробелов в столбце Id, поскольку в вопросе нет упоминания о последовательности пробелов в идентификаторах.


Edit2: Ответ на обновленный вопрос:

Я обновил CTE в приведенном выше запросе, чтобы он соответствовал вашему последнему варианту - или мне так кажется.

Используйте те столбцы, которые определяют последовательность строк. Добавьте столько столбцов в ваше предложение ORDER BY, сколько необходимо для разрыва связей.

Объяснение вашего последнего обновления мне не совсем понятно, но я думаю вам нужно всего лишь нажать DateTimeTrx, чтобы добиться того, чего вы хотите. У меня есть SeqNumber в ORDER BY, чтобы разорвать связи, оставленные идентичными DateTimeTrx. Я редактировал запрос выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...