У меня есть таблица, как показано ниже:
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]
Надеюсь, я объяснил это правильно. Что я делаю? Любой запрос, чтобы исправить это, пожалуйста?
Примечание. Записи поступают динамически, поэтому их нельзя жестко закодировать (если есть).
Спасибо.
если «RequestNumber» и «Date» совпадают (как показано в примере), то все записи объединяются, чтобы предоставить строку «Все три». Потому что «TrackName» имеет только 3 категории (т.е. средний, задний и передний).
Это означает, что остальные 2 строки должны быть удалены, верно?
да. Но вывод должен быть таким, как показано.
Я думаю, вы хотите 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'
Вы хотите, чтобы обе записи с 0762 оставались там с TrackName = 'Все три'? или хочет удалить и вторую строку?