SQL: вывод последнего пункта назначения каждого поезда

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для извлечения записей с наиболее поздней датой в каждой группе можно использовать подзапрос или общее табличное выражение (CTE). Сперва определяем наибольшую дату для каждой группы, а затем соединяем полученный результат с исходной таблицей:

SQL
Скопировать код
WITH RankedGroups AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY group_col ORDER BY date_col DESC) as rn
    FROM my_table
)
SELECT *
FROM RankedGroups
WHERE rn = 1;

Пожалуйста, замените my_table, group_col и date_col на реальные имена вашей таблицы и столбцов. Функция ROW_NUMBER() присваивает уникальные номера строкам внутри групп, определённых по group_col и упорядоченных по date_col в порядке убывания, поэтому условие rn = 1 выбирает строки с самой поздней датой в каждой группе.

Кинга Идем в IT: пошаговый план для смены профессии

Использование подзапросов и обработка ошибок

С точки зрения производительности и для предотвращения ошибок подзапросы являются надёжным средством. Они помогают избежать распространенной ошибки, когда в GROUP BY включаются столбцы без агрегации, тем самым предотвращая SQL-сбои:

SQL
Скопировать код
SELECT mt.*
FROM my_table mt
INNER JOIN (
    SELECT group_col, MAX(date_col) AS MaxDate
    FROM my_table
    GROUP BY group_col
) sub ON mt.group_col = sub.group_col AND mt.date_col = sub.MaxDate;

Освойте силу оконных функций

Не пропустите возможность использования оконных функций SQL, таких как RANK() или DENSE_RANK(), они смогут оказаться полезны в сложных случаях группировки и сортировки:

SQL
Скопировать код
WITH RankedDestinations AS (
    SELECT *, DENSE_RANK() OVER (PARTITION BY group_col ORDER BY date_col DESC) AS dest_rank
    FROM my_table
)
SELECT *
FROM RankedDestinations
WHERE dest_rank = 1;

Сценарий из реальной жизни

Представьте выставку искусства, на которой художники представляют несколько работ:

Markdown
Скопировать код
| Художник | Даты выставок |
| -------- | ------------- |
| 🎨A       | 1 янв, 5 янв, 10 янв |
| 🎨B       | 2 янв, 3 янв, 9 янв |

Было бы замечательно увидеть только последние картины каждого художника:

SQL
Скопировать код
SELECT Artist, MAX(Exhibition Dates)
GROUP BY Artist;

Таким образом, публика сможет оценить последние шедевры:

Markdown
Скопировать код
| 🎨 | Последний шедевр |
| -- | --------------- |
| A  | 10 янв 🖼️       |
| B  | 9 янв 🖼️        |

Теперь благодаря использованию GROUP BY с MAX(DATE) последние работы художников предстанут перед вниманием зрителей.

Мы легко справляемся со сложными ситуациями

Дуэль одинаковых дат

При наличии одинаковых максимальных дат можно установить приоритет, применив условия в функции ранжирования:

SQL
Скопировать код
WITH RankedValues AS (
    SELECT *, 
           ROW_NUMBER() OVER (
                PARTITION BY group_col 
                ORDER BY date_col DESC, tiebreaker_col ASC
           ) AS rn
    FROM my_table
)
SELECT *
FROM RankedValues
WHERE rn = 1;

Агент KEEP во власти

Для любителей элегантных SQL-решений, например в базе данных Oracle, пригодится функциональность KEEP:

SQL
Скопировать код
SELECT group_col, 
       MAX(date_col) KEEP (DENSE_RANK FIRST ORDER BY date_col DESC) AS LatestDate
FROM my_table
GROUP BY group_col;

Пусть этот трюк останется между нами, мастерами SQL. 😉

K.I.S.S (Коротко и ясно)

Сложные и длинные запросы всего лишь делают голову больной. Посмотрите на эту компактность записи:

SQL
Скопировать код
SELECT mt.*, t.MaxDate
FROM my_table mt
JOIN LATERAL (
    SELECT MAX(date_col) AS MaxDate
    FROM my_table t1
    WHERE mt.group_col = t1.group_col
) t ON mt.date_col = t.MaxDate;

Как известно, лаконичность – знак профессионализма.

Полезные материалы

  1. Недавние вопросы по теме 'sql+group-by+max' на Stack Overflow — Присоединяйтесь к SQL-сообществу для обсуждения 'GROUP BY' и 'MAX'.
  2. Обучающая статья по SQL GROUP BY на W3Schools — Пошаговые инструкции с понятными примерами.
  3. Основы SQL GROUP BY на Simple Talk — Освойте простые и сложные примеры использования GROUP BY с функциями MAX и MIN.
  4. SQLBolt – Урок 10: Запросы с агрегатами (Часть 1) — Изучите возможности GROUP BY и узнайте, как он работает в сочетании с HAVING и MAX(Date).

Завершение

Не прерывайте свои тренировки и совершенствуйте свое владение SQL. Чем больше практики — тем меньше ошибок. Поставьте лайк, если статья оказалась полезной, и помните о хорошем настроении. Всем успешного кодирования! 👩‍💻👨‍💻