Условие

Дана таблица с колонками 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 стоило бы выделить тип карты в отдельный столбец (нормализация).
Подводные камни
LIKEчувствителен к регистру в PostgreSQL.LIKE '%debit%'не найдётDEBIT. ИспользуйтеILIKEилиLOWER().INс большим списком — медленный. Сотни ID — терпимо, тысячи — лучше черезJOINсо временной таблицей.*в проде — нежелательно: тащит лишние колонки. В тесте вопроса это допустимо.
Эталонный ответ
B (CARD_NAME LIKE '%DEBIT%') и C (CARD_ID IN ('23450067','23458301','23450022')) — оба возвращают всех трёх дебетовых клиентов. LIKE предпочтителен с точки зрения семантики.