обновить столбец, если несколько записей других столбцов одной таблицы совпадают - PullRequest
0 голосов
/ 28 мая 2019

У меня есть таблица, как показано ниже:

            Input table:
            RequestNumber            TrackName         Date
            -----------------------------------------------------------
            02209                    Middle         2017-05-28 00:00:00
            0263                     Middle         2017-06-29 00:00:00
            0633                     Middle         2017-09-10 00:00:00
            0762                     Back           2017-06-23 00:00:00
            0762                     Front          2017-06-23 00:00:00
            0762                     Middle         2017-06-23 00:00:00
            01839                    Middle         2017-03-09 00:00:00

Мне нужно проверить, совпадают ли «RequestNumber» и «Date» для «TrackName».если несколько повторных записей «RequestNumber» и «Date» совпадают, я должен обновить столбец «TrackName» как «All three», как показано в примере ниже (в этом примере есть 3 соответствующие записи)

            Output table:
            RequestNumber            TrackName         Date
            -----------------------------------------------------------
            02209                    Middle         2017-05-28 00:00:00
            0263                     Middle         2017-06-29 00:00:00
            0633                     Middle         2017-09-10 00:00:00
            0762                     All three      2017-06-23 00:00:00
            01839                    Middle         2017-03-09 00:00:00

Toполучить описанный выше вывод, это SQL, который я пробовал.Howveer, он обновляет все TrackName на All three.

            UPDATE a 
            SET a.[TrackName] = 'All three'
            FROM Table1 as a
            INNER JOIN 
            (SELECT [RequestNumber], row_number() OVER (ORDER BY [RequestNumber] DESC) as rowNumber
            FROM Table1 ) drRowNumbers ON drRowNumbers.[RequestNumber] = a.[RequestNumber] and drRowNumbers.[Date] = a.[Date]

Надеюсь, я все правильно объяснил.Что я делаю?Любой запрос, чтобы исправить это, пожалуйста?

Примечание: записи поступают динамически, поэтому не могут быть жестко закодированы (если есть).

Спасибо.

Ответы [ 4 ]

1 голос
/ 28 мая 2019

Попробуйте это.Это вернет «Все 3» вместо «Все три» -

SELECT RequestNumber,
CASE 
    WHEN COUNT(*) = 1 THEN MAX(TrackName) 
    ELSE 'All ' + CAST( COUNT(*) AS VARCHAR) 
END TrackName,
Date
FROM your_table
GROUP BY RequestNumber,Date
0 голосов
/ 28 мая 2019

Дайте этому попытку

шаг 1 установить одну из записей на все три

update table1
set TrackName = 'All Three'
where requestnumber in (select requestnumber
from table1
group by requestnumber,[date]
having count(*) = 3)
and trackname = 'Front'

шаг 2 удалить данные больше не нужны

delete table1
where requestnumber in (select requestnumber
from table1
group by requestnumber,[date]
having count(*) = 3)
and trackname <> 'All Three'
0 голосов
/ 28 мая 2019

Это не просто обновление, это также удаление.
Это означает, что у вас должен быть двухэтапный процесс - один для обновления соответствующих записей, а другой для удаления дубликатов, созданных на первом шаге.

Это можно сделать с помощью пары общих табличных выражений, которые используют оконные функции, такие как count() over() и row_number() over(), когда оба шага объединяются внутри транзакции.

Сначала создайте и заполните образец таблицы ( Пожалуйста, сохраните нам этот шаг в своих будущих вопросах):

DECLARE @T AS TABLE
(
    RequestNumber int,
    TrackName varchar(10),
    [Date] datetime2
);

INSERT INTO @T (RequestNumber, TrackName, Date) VALUES
(02209, 'Middle', '2017-05-28 00:00:00'),
(0263, 'Middle', '2017-06-29 00:00:00'),
(0633, 'Middle', '2017-09-10 00:00:00'),
(0762, 'Back', '2017-06-23 00:00:00'),
(0762, 'Front', '2017-06-23 00:00:00'),
(0762, 'Middle', '2017-06-23 00:00:00'),
(01839, 'Middle', '2017-03-09 00:00:00');

Далее запустите блок try итранзакция:

BEGIN TRY
BEGIN TRANSACTION;

Затем определите и обновите соответствующие записи:

WITH CTE AS
(
    SELECT  RequestNumber, 
            TrackName, 
            Date,
            COUNT(TrackName) OVER(PARTITION BY RequestNumber, Date) As Cnt
    FROM @T
)

UPDATE CTE
SET TrackName = 'All Three'
WHERE Cnt = 3;

Затем удалите дубликаты:

WITH CTE AS
(
    SELECT  RequestNumber, 
            TrackName, 
            Date,
            ROW_NUMBER() OVER(PARTITION BY RequestNumber, Date ORDER BY TrackName) As Rn
    FROM @T
)

DELETE 
FROM CTE 
WHERE Rn > 1;

Подтвердите транзакцию и закройтеtry block:

COMMIT TRANSACTION;
END TRY

Используйте блок catch для отката транзакции:

BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION

    -- you might want to print the result of ERROR_MESSAGE() here...
END CATCH

И, наконец, выберите, чтобы увидеть изменения:

SELECT  RequestNumber, 
        TrackName, 
        Date
FROM @T

Результаты:

RequestNumber   TrackName   Date
2209            Middle      28.05.2017 00:00:00
263             Middle      29.06.2017 00:00:00
633             Middle      10.09.2017 00:00:00
762             All Three   23.06.2017 00:00:00
1839            Middle      09.03.2017 00:00:00

Вы можете увидеть живое демо на rextester (за исключением части транзакции, которая там не разрешена, и попытки ... поймать, которая не актуальна безтранзакция в любом случае)

0 голосов
/ 28 мая 2019

Я думаю, что вы хотите SELECT заявление:

SELECT t1.RequestNumber, (CASE WHEN COUNT(DISTINCT t1.TrackName) = t2.TrackNo 
                               THEN CONCAT('All ', t2.TrackNo)  
                               ELSE MIN(t1.TrackName) 
                          END) AS TrackName, t1.Date
FROM table1 t1 CROSS JOIN
     (SELECT COUNT(DISTINCT TrackName) AS TrackNo FROM table1) AS t2
GROUP BY t1.RequestNumber, t1.Date;
...