#sql #sql-server #tsql #sql-update
#sql #sql-сервер #tsql #sql-обновление
Вопрос:
У меня есть table A
, с 2 основными столбцами: Name
и Settings
. Settings
Столбец будет иметь 3 значения: 1, 2 или 3.
Например:
Name Settings
Andre 1
Andre 1
Betty 3
Charles 1
Charles 1
Обратите внимание, что у 1 Name
может быть только 1 Settings
: 1, 2 или 3
У меня есть другой table B
, с 2 основными столбцами: Name
и Type
. Type
Столбец состоит из 3 значений: 'TypeA'
, 'TypeB'
и 'TypeC'
.
Например:
Name Type
Andre TypeA
Andre TypeA
Andre TypeC
Betty TypeB
Betty TypeB
Charles TypeB
Charles TypeA
Charles TypeA
Обратите внимание, что 1 Name
может иметь несколько одинаковых или неодинаковых значений Type
. И мы не рассматриваем about TypeC
, только TypeA
и TypeB
.
Теперь я хочу обновить Settings
столбец из table A
, используя 'Type'
столбец из table B
, если:
Type
Столбец изtable B
имеет значение'TypeA'
, затем установите для всех записей, которые имеют одинаковое значениеName
для обеих таблиц, значение 1 вSettings
столбце изtable A
.Type
Столбец изtable B
имеет значение'TypeB'
, затем установите для всех записей, которые имеют одинаковое значениеName
для обеих таблиц, значение 2 вSettings
столбце изtable A
.Type
Столбец изtable B
имеет оба значения'TypeA'
и'TypeB'
, затем установите для всех записей, которые имеют одинаковое значениеName
для обеих таблиц, значение 3 вSettings
столбце изtable A
.
Результат из table A
станет таким:
Name Settings
Andre 1
Andre 1
Andre 1
Betty 2
Charles 3
Charles 3
Ответ №1:
Похоже, вам нужна инструкция update join:
UPDATE a
SET settings = CASE type WHEN 'TypeA' THEN 1
WHEN 'TypeB' THEN 2
END
FROM tablsA a
JOIN tableB b ON a.name = b.name
WHERE type IN ('TypeA', 'TypeB') -- just a precaution
Комментарии:
1. Крайне необходимая мера предосторожности, в противном случае другие (не совпадающие) типы будут обновлены до NULL, если вы не добавили предложение where..
2. @RaymondNijland ага, вот почему это там. Из описания операции неясно, действительно ли в таблице есть другие типы или нет. хотя.
3. Действительно, все же я бы добавил в ELSE type = type в предложении case в качестве дополнительной подстраховки для случаев, когда предложение WHERE и оператор CASE не совпадают, это может произойти при написании больших запросов.. Но все же, кто будет выполнять такого рода запросы в производственной базе данных, не протестировав их на маленькой копии производственной базы данных в качестве теста
4. @Mureinik вы правы, в столбце «Тип» больше значений, но я просто рассматриваю «TypeA» и «TypeB» для моего запроса. Также есть еще одно условие, которое я забыл добавить, просто отредактировал вопрос. В любом случае спасибо 🙂
Ответ №2:
В этом случае я вижу более одного варианта.
Вы могли бы рассмотреть возможность нормализации этих таблиц и добавления внешнего ключа с каскадированием обновлений.
Вы могли бы заменить одну из этих таблиц просто представлением и сопоставлением значений; это зависит от того, какую таблицу можно обновить. Если оба получают обновления, это решение может работать, только если вы используете индексированные представления.
Если у вас разные или перекрывающиеся настройки для разных типов, возможно, также с зависимостями от пользователей, вам может понадобиться таблица сопоставления, в которой вы сопоставляете тип с настройками.
Также возможно использовать триггеры для этих целей, чтобы обеспечить согласованность, но вы должны предпочесть правильную компоновку таблицы с правильными внешними ключами.
Это также может помочь предоставить более подробную информацию о вашем варианте использования.
Ответ №3:
Один из методов заключается в агрегировании второй таблицы перед JOIN
вводом:
UPDATE a
SET settings = (CASE WHEN num_a > 0 AND num_b = 0 THEN 1
WHEN num_b > 0 THEN 2
ELSE 3
END)
FROM tablsA a JOIN
(SELECT b.name,
SUM(CASE WHEN type = 'TypeA' THEN 1 ELSE 0 END) as num_a,
SUM(CASE WHEN type = 'TypeB' THEN 1 ELSE 0 END) as num_B
FROM tableB b
GROUP BY b.name
) b
ON a.name = b.name