T-SQL: таблица UPDATE в соответствии со столбцом - PullRequest
0 голосов
/ 25 июня 2019

TLDNR : как обновить таблицу в зависимости от столбца?

Проблемная ситуация : текущий столбец SortingNumber полон неверных данных.

Решение : переназначить новые значения на SortingNumber на основе их Parent. SortingNumber должно быть 1 для самого низкого тока SortingNumber (на Parent) и увеличиваться на 1 для каждого последующего набора данных.

Current data:                         Desired result:

ID | Parent | SortingNumber   >>      ID | Parent | SortingNumber 
1  |   1    |   3             >>      1  |   1    |   1 
2  |   1    |   4             >>      2  |   1    |   2 
3  |   1    |   5             >>      3  |   1    |   3 
4  |   2    |   8             >>      4  |   2    |   1           
5  |   2    |   10            >>      5  |   2    |   2           
6  |   2    |   13            >>      6  |   2    |   3          

Актуальная проблема : У меня проблемы с выяснением того, как обновить наборы данных, соответствующие их родителям.

Мой скрипт в настоящее время обновляет все значения постепенно и не группирует его по Parent.

Мое текущее решение:

DECLARE @lastSN INTEGER = 0;

WITH toUpdate AS
(
    SELECT 
        T1.*,
        -- "calculate" the sorting number from the row above    
        LAG(T1.SortingNumber + 1, 1, 1) OVER (ORDER BY T1.SortingNumber) AS [newSortNumber]
    FROM 
        T AS T1 
    INNER JOIN 
        T AS T2 ON T1.Parent = T2.ID
)
UPDATE toUpdate
SET
    @lastSN = CASE WHEN [newSortNumber] = 1 AND @lastSN = 0 THEN 1 ELSE @lastSN + 1 END,
    toUpdate.SortingNumber = @lastSN 
;

Результат:

    ID | Parent | SortingNumber   
    1  |   1    |   1             
    2  |   1    |   2             
    3  |   1    |   3             
    4  |   2    |   4             
    5  |   2    |   5            
    6  |   2    |   6

Полагаю, мой вопрос можно сформулировать так: как обновить наборы данных в зависимости от столбца Parent?

PS : вот выражение CREATE, если вы хотите попробовать его сами

CREATE TABLE T 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    Parent INT FOREIGN KEY REFERENCES T(ID),
    SortingNumber INT
);   
GO  

INSERT INTO T (Parent, SortingNumber) 
VALUES (1, 3), (1, 4), (1, 5), (2, 8), (2, 10), (2, 13);

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Вы можете использовать row_number для достижения этого, используя разбиение по Parent и упорядочение по SortingNumber.

WITH cte AS (
SELECT 
    * ,  
    ROW_NUMBER() OVER (PARTITION BY Parent ORDER BY SortingNumber) AS NewSortingNumber
FROM T

)
UPDATE cte
SET SortingNumber = NewSortingNumber

Оконная функция создает небольшие таблицы в таблице, используя Parent, поэтому у нас есть два подмножества, одно для Parent = 1 и другое для Parent = 2. Затем она использует ORDER BY, чтобы узнать, с какой строки она должна начинаться считать ( начиная с 1). Первая строка для Parent = 1 и ID = 1, поэтому она получает 1, следующая строка получает 2 и т. Д. Пожалуйста, посмотрите здесь больше деталей .

0 голосов
/ 25 июня 2019

В качестве альтернативы вы можете просто ранжировать, упорядочив по пациенту, затем ID:

UPDATE tt

SET sortingnumber = drank from (select *, DENSE_RANK() OVER (order by Parent, ID) as drank from tt ) a where tt.ID=a.id and tt.parent=a.parent

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