Разбор задачек с собеседований vol. 1
Что-то в последнее время мало разбирали задачек 🙃
При этом это формат 1 apple a day keeps the doctor away 🍏 - вроде и не ботаете активно, но держите себя в форме, проверяя, что помните основные концепты. Так что исправляемся 😉
Погнали. Задачка с интервью в Умскул.
Схема БД:
Задача:
Прежде чем вывести решение, вдумчиво прочитаем условие и поймем, что это значит.
➡️ Вывести нужно все программы
У вас могут быть программы без заказов, что вас сразу обязывает к LEFT JOIN, а не JOIN.
➡️ Есть фильтр, влияющий только на одну из таблиц
Вы хотите учитывать только оплаченные заказы, но это фильтрует только (!) orders. programs не фильтруются, а это значит, что нужно или использовать подзапрос / CTE, или фильтровать через join (это сейчас покажу).
❗️ Важно - мы прочитали каждое предложение и поняли, как мы это внедрим в код. На реальном собеседовании вам тоже нужно будет убедиться, что вы используете условие полностью.
Теперь решение:
SELECT
p.id,
p.name,
COALESCE(SUM(o.order_sum), 0) AS total_sales
FROM programs p
LEFT JOIN orders o
ON p.id = o.program_id
AND o.state = 'success'
GROUP BY p.id, p.name
ORDER BY total_sales DESC;
В принципе, у нас тут было два варианта - или сначала фильтрануть orders, или сделать left join на o.state = 'success'. На мой взгляд, решение выше более элегантное. Но так тоже сработает:
SELECT
p.id,
p.name,
COALESCE(SUM(o.order_sum), 0) AS total_sales
FROM programs p
LEFT JOIN
(SELECT *
FROM orders
WHERE state = 'success') o
ON p.id = o.program_id
GROUP BY p.id, p.name
ORDER BY total_sales DESC;
Если хотите что-нибудь конкретное разобрать, накидывайте задачки в комменты 🤑
А так жду ваших 🔥 и готовлюсь к следующим сериям 🥰
Что-то в последнее время мало разбирали задачек 🙃
При этом это формат 1 apple a day keeps the doctor away 🍏 - вроде и не ботаете активно, но держите себя в форме, проверяя, что помните основные концепты. Так что исправляемся 😉
Погнали. Задачка с интервью в Умскул.
Схема БД:
Таблица `orders` (order_id, user_id, program_id, order_date, buy_date, state, order_sum)
Таблица `programs` (id, name, type, direction)
Задача:
Вывести все программы и сумму продаж по ним, отсортировать по убыванию суммы продаж. Нужно учесть только оплаченные заказы (state = 'success').
Прежде чем вывести решение, вдумчиво прочитаем условие и поймем, что это значит.
➡️ Вывести нужно все программы
У вас могут быть программы без заказов, что вас сразу обязывает к LEFT JOIN, а не JOIN.
Читаете условие - сразу думаете, что будет, если у программы нет ордеров. Или если есть ордера без программы. Проще говоря, о null'ах. И как вы это обходите в решении.
➡️ Есть фильтр, влияющий только на одну из таблиц
Вы хотите учитывать только оплаченные заказы, но это фильтрует только (!) orders. programs не фильтруются, а это значит, что нужно или использовать подзапрос / CTE, или фильтровать через join (это сейчас покажу).
Видите фильтр - сразу себе отмечаете, на какие таблицы он реально должен влиять.
❗️ Важно - мы прочитали каждое предложение и поняли, как мы это внедрим в код. На реальном собеседовании вам тоже нужно будет убедиться, что вы используете условие полностью.
Теперь решение:
SELECT
p.id,
p.name,
COALESCE(SUM(o.order_sum), 0) AS total_sales
FROM programs p
LEFT JOIN orders o
ON p.id = o.program_id
AND o.state = 'success'
GROUP BY p.id, p.name
ORDER BY total_sales DESC;
В принципе, у нас тут было два варианта - или сначала фильтрануть orders, или сделать left join на o.state = 'success'. На мой взгляд, решение выше более элегантное. Но так тоже сработает:
SELECT
p.id,
p.name,
COALESCE(SUM(o.order_sum), 0) AS total_sales
FROM programs p
LEFT JOIN
(SELECT *
FROM orders
WHERE state = 'success') o
ON p.id = o.program_id
GROUP BY p.id, p.name
ORDER BY total_sales DESC;
Если хотите что-нибудь конкретное разобрать, накидывайте задачки в комменты 🤑
А так жду ваших 🔥 и готовлюсь к следующим сериям 🥰