LAG работает, LEAD возвращает 1 в том же заявлении

Я озадачен тем, что LEAD всегда возвращает ID = 1, который даже не является идентификатором в таблице (идентификатор начинается с ~ 18k), вместо действительного идентификатора для следующей записи. Значения NULL находятся там, где они должны быть, это просто строки, которые должны содержать действительный идентификатор. LAG с тем же синтаксисом работает, как ожидалось, возвращая правильные значения. LEAD даже не работает (правильно), когда я комментирую LAG. Кстати, я скопировал код (и просто изменил имена таблиц и столбцов) из другого моего скрипта, где он работал нормально.

UPDATE PRJ SET 
    PrevJob = SRC.PrevID,  -- << write Previous ID
    NextJob = SRC.NextID   -- << write Next ID
FROM PRJ as PRJ
LEFT JOIN  (
      SELECT 
          ID,  -- << ID for joining to the original record
          LAG(ID)  OVER (PARTITION BY RPCode,PNInt ORDER BY OrderNo) AS PrevID, -- << previous works
          LEAD(ID) OVER (PARTITION BY RPCode,PNInt ORDER BY OrderNo) AS NextID  -- << next returns 1
      FROM PRJ as PRJ2 
      ) as SRC ON SRC.ID = PRJ.ID

Вот пример результатов с помощью SELECT (см. Значения 1 в последнем столбце):

ID       PNInt       RPCode               OrderNo PrevJob              NextJob
-------- ----------- -------------------- ------- -------------------- -------
18783    53          00005320171113120000 1       NULL                 1
18795    53          00005320171113120000 2       18783                1
18789    53          00005320171113120000 3       18795                NULL
18784    53          00005320171127120000 1       NULL                 1
18796    53          00005320171127120000 2       18784                1
18790    53          00005320171127120000 3       18796                NULL
18785    53          00005320171211120000 1       NULL                 1
18797    53          00005320171211120000 2       18785                1
18791    53          00005320171211120000 3       18797                NULL
18786    53          00005320171225120000 1       NULL                 1
18798    53          00005320171225120000 2       18786                1
18792    53          00005320171225120000 3       18798                NULL
18787    53          00005320180108120000 1       NULL                 1
18799    53          00005320180108120000 2       18787                1
18793    53          00005320180108120000 3       18799                NULL

Боюсь, это может быть какая-то глупая опечатка, которую я слепой видеть. Или есть какие-то зацепки с LAG и LEAD?


person Oak_3260548    schedule 20.11.2017    source источник
comment
1. Измените свой вопрос, включив в него образцы данных как DDL + DML (создавать операторы и вставлять в операторы). 2. Попробуйте запустить select без update и посмотрите, что вы получите для столбца NextID. 3. Попробуйте изменить псевдоним таблицы в операторе обновления на другое, чем имя таблицы. 4. Если ничего не помогает, попробуйте использовать lag с order by desc вместо lead 5. Если и это не помогло - перезапустите и повторите попытку.   -  person Zohar Peled    schedule 20.11.2017
comment
Добавьте RPCode к результатам вашего образца. Может есть проблема.   -  person Rokuto    schedule 20.11.2017
comment
Какие данные находятся в поле RPCode? Я вижу, что все значения в PNInt одинаковы.   -  person Denis Rubashkin    schedule 20.11.2017
comment
Не уверен, почему вам нужно сделать это как подзапрос. Вы бы лучше использовали CTE, а затем обновляли CTE. Для этого требуется только один анализ таблицы, а не два. Зохар прав, нет данных DDL и Sample, нет ответа.   -  person Larnu    schedule 20.11.2017
comment
На мой взгляд, ваше решение должно работать. Ссылка на sqlfiddle.   -  person Rokuto    schedule 20.11.2017
comment
Вы пытались сделать только ВЫБОР, а не ОБНОВЛЕНИЕ? это может быть какой-нибудь триггер на вашем столе?   -  person sepupic    schedule 20.11.2017
comment
Спасибо за все предложения. Это было автодополнение для NextID в схеме таблицы, я установил бит вместо bigint. Прежде чем я успел поставить это под сомнение, Гордон Линофф указал на это, что нужно проверить, и я нашел проблему.   -  person Oak_3260548    schedule 20.11.2017


Ответы (2)


Во-первых, вы можете написать это гораздо проще:

UPDATE toupdate
    SET PrevJob = SRC.PrevID,  -- << write Previous ID
        NextJob = SRC.NextID   -- << write Next ID
FROM (SELECT PRJ.*, 
             LAG(ID)  OVER (PARTITION BY RPCode, PNInt ORDER BY OrderNo) AS new_PrevID, -- << previous works
             LEAD(ID) OVER (PARTITION BY RPCode, PNInt ORDER BY OrderNo) AS new_NextID  -- << next returns 1
      FROM PRJ
     ) toupdate;

Я не могу объяснить поведение, которое вы видите. Две вещи, которые нужно проверить:

  • Тип полей идентификатора.
  • Любые триггеры, которые могут быть определены в таблице.
person Gordon Linoff    schedule 20.11.2017
comment
О, мать-природа ... В тот момент, когда я увидел ваш комментарий о типе поля, я понял, что должен сделать ошибку, и вот она, я случайно установил для поля Next значение битового типа данных. Вероятно, из-за автодополнения (bit вместо bigint). Большое тебе спасибо. - person Oak_3260548; 20.11.2017

Невозможно воспроизвести вашу проблему, см. этот скрипт SQL

Настройка схемы MS SQL Server 2014:

CREATE TABLE PRJ
    ([ID] int, [PNInt] int, [RPCode] varchar(20), [OrderNo] int, [PrevJ] varchar(5), [NextJ] varchar(4))
;

INSERT INTO PRJ
    ([ID], [PNInt], [RPCode], [OrderNo], [PrevJ], [NextJ])
VALUES
    (18783, 53, 'O0005320171113120000', 1, NULL, '1'),
    (18795, 53, 'O0005320171113120000', 2, '18783', '1'),
    (18789, 53, 'O0005320171113120000', 3, '18795', NULL),
    (18784, 53, 'O0005320171127120000', 1, NULL, '1'),
    (18796, 53, 'O0005320171127120000', 2, '18784', '1'),
    (18790, 53, 'O0005320171127120000', 3, '18796', NULL),
    (18785, 53, 'O0005320171211120000', 1, NULL, '1'),
    (18797, 53, 'O0005320171211120000', 2, '18785', '1'),
    (18791, 53, 'O0005320171211120000', 3, '18797', NULL),
    (18786, 53, 'O0005320171225120000', 1, NULL, '1'),
    (18798, 53, 'O0005320171225120000', 2, '18786', '1'),
    (18792, 53, 'O0005320171225120000', 3, '18798', NULL),
    (18787, 53, 'O0005320180108120000', 1, NULL, '1'),
    (18799, 53, 'O0005320180108120000', 2, '18787', '1'),
    (18793, 53, 'O0005320180108120000', 3, '18799', NULL)
;

Запрос 1:

      SELECT 
          ID,  -- << ID for joining to the original record
          LAG(ID)  OVER (PARTITION BY RPCode,PNInt ORDER BY OrderNo) AS PrevID, -- << previous works
          LEAD(ID) OVER (PARTITION BY RPCode,PNInt ORDER BY OrderNo) AS NextID  -- << next returns 1
      FROM PRJ as PRJ2 

Результаты:

|    ID | PrevID | NextID |
|-------|--------|--------|
| 18783 | (null) |  18795 |
| 18795 |  18783 |  18789 |
| 18789 |  18795 | (null) |
| 18784 | (null) |  18796 |
| 18796 |  18784 |  18790 |
| 18790 |  18796 | (null) |
| 18785 | (null) |  18797 |
| 18797 |  18785 |  18791 |
| 18791 |  18797 | (null) |
| 18786 | (null) |  18798 |
| 18798 |  18786 |  18792 |
| 18792 |  18798 | (null) |
| 18787 | (null) |  18799 |
| 18799 |  18787 |  18793 |
| 18793 |  18799 | (null) |
person Paul Maxwell    schedule 20.11.2017
comment
Я попробовал ваше предложение, но обновление по-прежнему возвращает 1 ... RPCode теперь предоставлен, извините, что забыл его в начале. - person Oak_3260548; 20.11.2017