#sql-server
#sql-server
Вопрос:
У меня есть таблица с набором строк с одинаковым кодом RecordtypeCode,
затем одна / установленная строка поступает из плоского файла / другого источника, как показано ниже,
наконец, мне нужна уникальная строка в моей таблице, удалив повторяющийся Recordtypecode и взяв максимум другой информации о поле,
Наконец, моей таблице должно понравиться это,
Что я пробовал прямо сейчас? Извлекаю все строки из моей таблицы и затем объединяю с новым набором записей, затем записываю хранимую процедуру (используя ключевое слово group by amp; max), чтобы получить желаемый результат во временной таблице, и, наконец, усекаю мою таблицу, а затем вставляю данные временной таблицы в мою таблицу.
Есть ли какие-либо другие лучшие способы избежать проблем с производительностью, потому что я собираюсь поиграть с миллионами записей здесь.
Ответ №1:
Сложно ответить без более подробной информации, но вы могли бы попробовать что-то подобное, чтобы получить сгруппированные результаты:
SELECT RecordTypeCode,
Max(AgeGroupFemale60_64),
Max(AgeGroupFemale65_69),
Max(AgeGroupFemale70_74)
FROM [TempTable]
GROUP BY RecordTypeCode
Комментарии:
1. Я использовал тот же запрос для его достижения, моя задача — удалить дубликат из самой таблицы.
Ответ №2:
Предполагая, что вы используете SQL Server 2005 , вы могли бы использовать MAX() OVER
для определения максимальных значений флага в каждой Recordtypecode
группе:
SELECT
Recordtypecode,
AgeGroupFemale60_64,
AgeGroupFemale65_69,
AgeGroupFemale70_74,
MAX(AgeGroupFemale60_64) OVER (PARTITION BY Recordtypecode),
MAX(AgeGroupFemale65_69) OVER (PARTITION BY Recordtypecode),
MAX(AgeGroupFemale70_74) OVER (PARTITION BY Recordtypecode)
FROM
dbo.TempTable
и обновите все флаги этими значениями:
WITH maximums AS (
SELECT
Recordtypecode,
AgeGroupFemale60_64,
AgeGroupFemale65_69,
AgeGroupFemale70_74,
MaxFemale60_64 = MAX(AgeGroupFemale60_64) OVER (PARTITION BY Recordtypecode),
MaxFemale65_69 = MAX(AgeGroupFemale65_69) OVER (PARTITION BY Recordtypecode),
MaxFemale70_74 = MAX(AgeGroupFemale70_74) OVER (PARTITION BY Recordtypecode)
FROM
dbo.TempTable
)
UPDATE
maximums
SET
AgeGroupFemale60_64 = MaxFemale60_64,
AgeGroupFemale65_69 = MaxFemale65_69,
AgeGroupFemale70_74 = MaxFemale70_74
;
Затем вы можете использовать ROW_NUMBER()
для перечисления всех строк в группах:
SELECT
*
rn = ROW_NUMBER() OVER (PARTITION BY Recordtypecode ORDER BY Recordtypecode)
FROM
dbo.TempTable
и удалите все строки с помощью rn > 1
:
WITH enumerated AS (
SELECT
*
rn = ROW_NUMBER() OVER (PARTITION BY Recordtypecode ORDER BY Recordtypecode)
FROM
dbo.TempTable
)
DELETE FROM
enumerated
WHERE
rn > 1
;
В качестве альтернативы, вместо двух операторов, UPDATE
и DELETE
, вы могли бы использовать один, MERGE
(который теперь предполагает SQL Server 2008 ), например:
WITH enumerated AS (
SELECT
*
rn = ROW_NUMBER() OVER (PARTITION BY Recordtypecode ORDER BY Recordtypecode)
FROM
dbo.TempTable
),
maximums AS (
SELECT
Recordtypecode,
MaxFemale60_64 = MAX(AgeGroupFemale60_64),
MaxFemale65_69 = MAX(AgeGroupFemale65_69),
MaxFemale70_74 = MAX(AgeGroupFemale70_74),
rn = 1
FROM
dbo.TempTable
GROUP BY
Recordtypecode
)
MERGE INTO
enumerated AS tgt
USING
maximums AS src
ON
tgt.Recordtypecode = src.Recordtypecode AND tgt.rn = src.rn
WHEN MATCHED THEN
UPDATE SET
tgt.AgeGroupFemale60_64 = src.MaxFemale60_64,
tgt.AgeGroupFemale65_69 = src.MaxFemale65_69,
tgt.AgeGroupFemale70_74 = src.MaxFemale70_74
WHEN NOT MATCHED THEN
DELETE
;
Дополнительная информация:
- Предложение OVER (Transact-SQL)
- СЛИЯНИЕ (Transact-SQL)
Обратите внимание, что существуют известные проблемы с оператором MERGE, о которых вам нужно знать, прежде чем принимать решение об его использовании. Вы можете начать с этой статьи, чтобы узнать о них больше и посмотреть, применимы ли какие-либо из них к вашей ситуации: