Собесов

SQL: вывести клиентов с дебетовой картой (несколько корректных вариантов)

SQLWHERE и шаблоныЛёгкаяJunior

Условие

Дана таблица с колонками ACCOUNT, NAME, CARD_NAME, CARD_ID. Пример:

ACCOUNT NAME CARD_NAME CARD_ID
1 Юля TBANK_DEBIT_BLACK 23450067
2 Саша TBANK_CREDIT_PLATINUM 58121263
3 Инна TBANK_DEBIT_DRIVE 23458301
4 Юра TBANK_DEBIT_BLANK 23450022
5 Ваня TBANK_CREDIT_ALLGAMES 52341134

Какой SELECT выведет всех клиентов с дебетовой картой? (Можно несколько верных)

  • A) SELECT * FROM TABLE WHERE CARD_ID = '23450067'
  • B) SELECT * FROM TABLE WHERE CARD_NAME LIKE '%DEBIT%'
  • C) SELECT * FROM TABLE WHERE CARD_ID IN ('23450067', '23458301', '23450022')
  • D) SELECT * FROM TABLE WHERE CARD_NAME = 'TBANK_DEBIT_BLACK'

Решение

Корректные варианты — B и C.

Разбор

  • A CARD_ID = '23450067' — выведет только Юлю (одну строку), а у нас 3 дебетовых клиента.
  • B CARD_NAME LIKE '%DEBIT%' — корректно: маска ловит TBANK_DEBIT_BLACK, TBANK_DEBIT_DRIVE, TBANK_DEBIT_BLANK. Все три дебетовые.
  • C CARD_ID IN (...) — корректно: явно перечисленные CARD_ID соответствуют именно дебетовым картам в данной выборке.
  • D CARD_NAME = 'TBANK_DEBIT_BLACK' — выведет только Юлю; остальных дебетовых не достанет.

Почему B лучше C в проде

  • B — маска по семантике. Если завтра появится TBANK_DEBIT_LITE — он тоже попадёт.
  • C — список ID. Жёстко привязан к текущим записям; новые карты придётся добавлять руками.

Эффективность

-- LIKE с ведущим % не использует обычный B-tree индекс по CARD_NAME
WHERE CARD_NAME LIKE '%DEBIT%'  -- full scan
 
-- IN по индексированному CARD_ID — fast
WHERE CARD_ID IN (...)  -- index seek
 
-- Идеал — отдельная колонка card_type
WHERE card_type = 'DEBIT'  -- index range

В реальной системе вместо LIKE стоило бы выделить тип карты в отдельный столбец (нормализация).

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

  1. LIKE чувствителен к регистру в PostgreSQL. LIKE '%debit%' не найдёт DEBIT. Используйте ILIKE или LOWER().
  2. IN с большим списком — медленный. Сотни ID — терпимо, тысячи — лучше через JOIN со временной таблицей.
  3. * в проде — нежелательно: тащит лишние колонки. В тесте вопроса это допустимо.

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

B (CARD_NAME LIKE '%DEBIT%') и C (CARD_ID IN ('23450067','23458301','23450022')) — оба возвращают всех трёх дебетовых клиентов. LIKE предпочтителен с точки зрения семантики.

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

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

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