Собесов

Градус: SQL — заполнение NULL в поле из связанной таблицы

SQLUPDATE и JOINЛёгкаяMiddle

Условие

В базе address есть таблица a. В некоторых строках поле [кодТТВх] равно NULL (таких строк 6353). Требуется написать SQL для заполнения этого поля. Возможно, поможет таблица b.

Решение

Подход

  1. Понять связь: какой ключ связывает a и b так, чтобы b.[кодТТВх] был известен.
  2. Если ключ — id_address или address_string — выполнить UPDATE ... FROM (Postgres) или UPDATE ... JOIN (MySQL/SQL Server).

PostgreSQL

UPDATE address.a AS a
SET "кодТТВх" = b."кодТТВх"
FROM address.b AS b
WHERE a.id = b.id                       -- предполагаемая связь
  AND a."кодТТВх" IS NULL
  AND b."кодТТВх" IS NOT NULL;

MySQL

UPDATE address.a a
JOIN address.b b ON b.id = a.id
SET a.кодТТВх = b.кодТТВх
WHERE a.кодТТВх IS NULL AND b.кодТТВх IS NOT NULL;

SQL Server

UPDATE a
SET кодТТВх = b.кодТТВх
FROM address.a a
INNER JOIN address.b b ON b.id = a.id
WHERE a.кодТТВх IS NULL AND b.кодТТВх IS NOT NULL;

Если связь по адресу/нечёткая

UPDATE address.a a
SET "кодТТВх" = b."кодТТВх"
FROM address.b b
WHERE a."кодТТВх" IS NULL
  AND b.region = a.region
  AND b.city   = a.city
  AND b.street = a.street
  AND (
    SELECT COUNT(*) FROM address.b b2
    WHERE b2.region=a.region AND b2.city=a.city AND b2.street=a.street
          AND b2."кодТТВх" IS NOT NULL
  ) = 1;                              -- однозначное соответствие

Sanity-check после UPDATE

SELECT COUNT(*) FROM address.a WHERE "кодТТВх" IS NULL;  -- должно убавиться

Подводные камни

  1. Не делайте UPDATE без WHERE и IS NULL — затрёте уже корректные значения.
  2. Если b содержит дубликаты по ключу, UPDATE FROM в Postgres возьмёт произвольную строку → недетерминированно. Нужно агрегировать или фильтровать дубли.
  3. Перед прод-апдейтом — BEGIN; ... ROLLBACK; для проверки или SELECT с тем же JOIN.
  4. Бэкап: CREATE TABLE a_backup AS SELECT * FROM a;
  5. Если в b тоже есть пропуски — IS NOT NULL обязательно.

Эталонный ответ

UPDATE a SET кодТТВх = b.кодТТВх FROM b WHERE a.<key>=b.<key> AND a.кодТТВх IS NULL AND b.кодТТВх IS NOT NULL; — синтаксис зависит от СУБД.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти