Обновить столбец, когда несколько записей других столбцов той же таблицы совпадают

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

            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» как «Все три», как показано ниже. пример вывода (в этом примере есть 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

Чтобы получить указанный выше результат, это SQL, который я пробовал. Тем не менее, он обновляет все TrackName до всех трех.

            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]

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

Примечание. Записи поступают динамически, поэтому их нельзя жестко закодировать (если есть).

Спасибо.

Вы хотите, чтобы обе записи с 0762 оставались там с TrackName = 'Все три'? или хочет удалить и вторую строку?

mkRabbani 28.05.2019 12:53

если «RequestNumber» и «Date» совпадают (как показано в примере), то все записи объединяются, чтобы предоставить строку «Все три». Потому что «TrackName» имеет только 3 категории (т.е. средний, задний и передний).

AskMe 28.05.2019 12:58

Это означает, что остальные 2 строки должны быть удалены, верно?

forpas 28.05.2019 12:59

да. Но вывод должен быть таким, как показано.

AskMe 28.05.2019 13:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
53
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Я думаю, вы хотите 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;
Ответ принят как подходящий

Попробуй это. Это вернет «Все 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

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

Это можно сделать с помощью пары общих табличных выражений, использующих оконные функции, такие как 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:

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 (минус часть транзакции, которая там не разрешена, и try...catch, которая в любом случае не актуальна без транзакции)

Попробуйте это

шаг 1 установите для одной из записей значение All Three

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'

Другие вопросы по теме