Большой запрос
Последние дни я безвылазно сижу в PGAdmin: пишу запрос, чтобы построить важный репорт. В нем уже 470 строк плюс понадобились пять функций для разных преобразований (например денег, округления дат). Итого 550 строк чистого скуля.
Не знаю, что обо мне скажут коллеги, когда это увидят. Наверное, проклянут и будут правы. Но дело в том, что у меня началась профдеформация: мне уже легче писать на SQL, чем на Кложе.
Со временем понимаешь следующий момент. В SQL любое значение — это таблица, а операторы — различные JOIN-ы: левое, правое, внутреннее или декартово произведение. Как только пришел к этому, мышление поворачивается под другим углом.
Скажем, вот список мап в Кложе:
[{:id 1 :name "Ivan"}
{:id 2 :name "Huan"}
{:id 3 :name "Juan"}]
То же самое в SQL:
id name
1 Ivan
2 Huan
3 Juan
Любая операция над этим списком сводится либо к фильтрации, либо джоину, либо
агрегатной функции. Скажем, фильтрация по ID это обычный where
:
select * from users where id > 2
То же самое, что написать:
(filter #(> % 2) users)
Предположим, есть список мап вида “пользователь -> аватар”. В SQL его легко выразить таблицей:
user_id photo_url
1 https://test.com/avatar.jpg
3 https://test.com/cat.jpg
А вот их различные объединения: с сохранением левой части (пользователи без аватары останутся):
select users.*, p.photo_url
from users u
left join photos p on p.user_id = u.id
id name photo_url
1 Ivan https://test.com/avatar.jpg
2 Huan
3 Juan https://test.com/cat.jpg
и без:
select users.*, p.photo_url
from users u
join photos p on p.user_id = u.id
id name photo_url
1 Ivan https://test.com/avatar.jpg
3 Juan https://test.com/cat.jpg
В общих словах, любой SQL-оператор сводится к джоину. Скажем, новички часто передают список айдишников с оператором IN:
where id in (1, 2, 3, ...999)
И не знают, что гораздо эффективнее выразить то же самое джоином и таблицей с
полем id
:
select * from users u
join user_ids on u.id = user_ids.id
В SQL даже одно значение является таблицей. Переменная x=42
— это таблица с
колонкой X
и кортежем (42, )
. Примерно как в Матлабе все является матрицей.
Есть расхожее мнение, что джоины тормозят, но вообще говоря это неправда. Джоины очень эффективны. Почти любой оператор можно ускорить, если свести его к джоину с другой таблицей. Если связующее поле индексировано, это будет быстро: почти как выборка. Важно, что выборка проекции двух и более таблиц быстрее, чем две отдельные выборки и обработка их силами Питона или другого языка.
Мышление таблицами и их проекциями — очень крутая вещь. Не знаю, во что это выльется, но чувствую себя как десять лет назад, когда ломал мозги об Кложу после императивного программирования. Волнует и возбуждает.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter