Comments 13
можно для "набивки руки" также использовать https://sql-ex.ru/
Вот корректный подход — фильтровать оплаченные транзакции прямо в
ON, чтобы не потерять клиентов без оплат
Не менее корректный подход - INNER JOIN + UNION. И он может оказаться даже более эффективным - впрочем, всё зависит от схемы и статистики данных. А ещё - сразу снимаются первые два дополнительных вопроса.
Решение чаще всего строят через ранжирование записей и накопление значений окна
За такое решение надо ставить жирный минус. Считать сумму 3 записей по всему массиву - это ж надо было придумать... всё агрегирование во внешнем запросе, а в CTE только нумерация.
WITH ranked AS (
SELECT
client_id,
trx_date,
amount,
ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY trx_date DESC) AS rn,
FROM transactions
)
SELECT client_id,
MAX(trx_date) AS last_trx_date,
SUM(amount) AS sum_last3_trx
FROM ranked
WHERE rn < 4
GROUP BY client_id;И я бы ещё затребовал пометку, у кого меньше трёх записей.
Вот корректный подход — фильтровать оплаченные транзакции прямо в
ON, чтобы не потерять клиентов без оплат:
А можно вот про это чуть подробнее? Решительно не понимаю как у вас исчезнут строки при "WHEREt.status = 'paid'", если "FROM clients c"
Может быть вы это утверждение писали для варианта у которого было "FROM transactions t" ?
Да элементарно. Если у товарища нет ни одного платежа, то нет ни одной записи с платежом, при LEFT JOIN в поле t.status (и остальных полях от таблицы платежей) будет сгенерировано значение NULL, условие t.status = 'paid' даст NULL, который интерпретируется как FALSE, и запись для этого товарища не попадёт в выходной набор.
Я против такого подхода
даст NULL, который интерпретируется как FALSE
Он просто не дает TRUE, этого достаточно. А то если вы возьмёте его отрицание, то "интерпретация" внезапно исчезнет
Он просто не дает TRUE, этого достаточно.
А вот это хоть и вроде бы верное утверждение, но на самом деле очень опасное заблуждение. Никогда не мыслите по шаблону - можете домыслиться до очень неприятных вещей. Например, в CHECK constraint полученное значение NULL интерпретируется как TRUE.
И тут не соглашусь. Значение null (или unknown) в check constraint просто исключаются из проверки. Считаю это более логичным объяснением, чем интерпретация как true. Впрочем это чисто эстетический момент, не влияющий на результат.
Значение null (или unknown) в check constraint просто исключаются из проверки.
Признаться, этой фразы не понял вообще.
На входе имеем запись, которую нужно проверить на соответствие условию.
На первом этапе безусловно вычисляется выражение ограничения. Только после этого этапа мы получаем значение для анализа, которое может быть в т.ч. и NULL. Следовательно, этот этап отпадает, фраза не о нём.
Далее выполняется блок, где на входе - значение проверяемого выражения, а на выходе - решение, соответствует ли запись ограничению либо нет. Вход - один (значение), выходов - два (соответствует либо не соответствует). И вашему "исключаются из проверки" как третьему пути течения процесса в этой схеме просто нет места.
А далее - далее просто ничего нет, вычисления выполнены, решения приняты, работа завершена. Так что в этом месте вашей фразе, пардон за тавтологию, уже не место.
Так что же вы на самом деле хотели сказать?
Да все вы поняли. На входе значение записи, на выходе значение из троичной логики (True, False, Unknown) - ограничение не проходит, когда на выходе строго False
ограничение не проходит, когда на выходе строго False
Вот и я о том же. Просто обычно как-то оперируют положительной логикой. "Если - то" даёт линейный ответ без дополнительной обработки. А когда начинается "если не - то", сразу начинаются затруднения, потому что надо рассматривать квадрат результат-действие.
Спасибо! Буду готовиться)
Хотелось бы увидеть не только рекламу курса, но и объяснения, решения.
SQL-собеседование без паники: что реально спрашивают и где валятся даже сильные