#sql #sql-server
Вопрос:
Мой приведенный ниже код плохо работает при попытке обновить таблицу, содержащую чуть более 100 000 строк.
У меня около 2500 значений, в которых первое значение в последовательности равно нулю, в результате эта строка и следующие последовательности не обновляются.
Кроме того, около 5000 строк также не обновляются, поскольку они не существуют во второй из двух таблиц (таблица 1 = dbo.abc / таблица 2 = dbo.abc_d)
Что касается второй проблемы, я могу написать второй запрос только для этой таблицы, но я застрял на первой проблеме. Если у вас есть какие-либо советы по улучшению этого запроса для любой проблемы, это было бы оценено.
UPDATE dbo.abc abc
SET vcn1 = ( CASE
WHEN abc.chan_id1 IS NOT NULL THEN abc.chan_id1
WHEN abc.chan_id2 IS NOT NULL THEN abc.chan_id2
WHEN abc.chan_id3 IS NOT NULL THEN abc.chan_id3
--omitting this chuck for readability
WHEN abc_d.chan_id34 IS NOT NULL THEN abc_d.chan_id34
WHEN abc_d.chan_id35 IS NOT NULL THEN abc_d.chan_id35
WHEN abc_d.chan_id36 IS NOT NULL THEN abc_d.chan_id36
END ),
vcn2 = ( CASE
WHEN abc.chan_id1 IS NOT NULL AND abc.chan_id1 != abc.vcn1 THEN abc.chan_id1
WHEN abc.chan_id2 IS NOT NULL AND abc.chan_id2 != abc.vcn1 THEN abc.chan_id2
WHEN abc.chan_id3 IS NOT NULL AND abc.chan_id3 != abc.vcn1 THEN abc.chan_id3
--omitting this chuck for readability
WHEN abc_d.chan_id34 IS NOT NULL AND abc_d.chan_id34 != abc.vcn1 THEN abc_d.chan_id34
WHEN abc_d.chan_id35 IS NOT NULL AND abc_d.chan_id35 != abc.vcn1 THEN abc_d.chan_id35
WHEN abc_d.chan_id36 IS NOT NULL AND abc_d.chan_id36 != abc.vcn1 THEN abc_d.chan_id36
END )
FROM dbo.abc_d abc_d
WHERE abc.abc_id = abc_d.abc_id;
Комментарии:
1. Я думаю, ваша проблема не ясна. В любом случае, не было бы проще, если бы вы заменили эти case when …. end на Coalesce(abc.chan_id1, abc.chan_id2, abc.chan_id3, … abc_d.chan_id34 …) Кстати, для второй проблемы вы могли бы использовать левое соединение.
2.Синтаксис, который у вас есть, недопустим; вы не можете использовать псевдоним таблицы в
UPDATE
предложении. Приведенное выше также приведет к возникновению ошибкиIncorrect syntax near 'abc'.
, этоCASE
выражение; оно возвращает скалярное значение.3. Ваша реальная проблема заключается в отсутствии нормализации: у вас не должно быть 36 одинаковых столбцов
4. @Charlieface, унаследованная мной база данных — это беспорядок … много таблиц с несколькими одинаковыми столбцами, как у меня в этом выпуске. Можете ли вы указать мне какие-либо ресурсы, которые могли бы указать мне путь к исправлению этой базы данных?
5. Может быть, начать здесь sqlshack.com/what-is-database-normalization-in-sql-server их должно быть много в Интернете, если вы пользуетесь Google
Ответ №1:
Вы можете использовать левое соединение для решения вашей второй проблемы. Ваша первая проблема не является проблемой:
UPDATE dbo.abc
SET vcn1 = coalesce( abc.chan_id1,
abc.chan_id2,
abc_d.chan_id34,
abc_d.chan_id35
),
vcn2 = ( CASE
WHEN abc.chan_id1 IS NOT NULL AND abc.chan_id1 != abc.vcn1 THEN abc.chan_id1
WHEN abc.chan_id2 IS NOT NULL AND abc.chan_id2 != abc.vcn1 THEN abc.chan_id2
WHEN abc_d.chan_id34 IS NOT NULL AND abc_d.chan_id34 != abc.vcn1 THEN abc_d.chan_id34
WHEN abc_d.chan_id35 IS NOT NULL AND abc_d.chan_id35 != abc.vcn1 THEN abc_d.chan_id35
END )
FROM dbo.abc abc
left join dbo.abc_d abc_d
on abc.abc_id = abc_d.abc_id;
Комментарии:
1. Привет, Четин. Я обновлю свои знания SQL и попробую опцию coalesce. Спасибо. Могу ли я также использовать coalesce во втором операторе case (VCN2)?
2. @RichardConaway, ну, во втором случае есть более сложное сравнение, которое на самом деле, я думаю, неверно, но я просто следовал вашему выражению. Coalesce(), похоже, не подходит для этого напрямую, но я действительно не понял, что вы пытаетесь там установить. Проверьте пример DbFiddle. Когда VCN1 равно NULL, сопоставление в любом случае завершается неудачно, а VCN2 равно NULL в конце. Вероятно, вместо этого вы имели в виду что-то вроде: vcn2 = ( СЛУЧАЙ, КОГДА abc.chan_id1 НЕ РАВЕН НУЛЮ И (abc.vcn1 равно нулю или abc.chan_id1 != abc.vcn1) ТОГДА abc.chan_id1 КОГДА …
3. FWIW
abc.chan_id1 IS NOT NULL AND abc.chan_id1 != abc.vcn1
NULL
проверка здесь не нужна, поскольку для проверки равенства [in], чтобы привести кtrue
нему, оно должно быть ненулевым !