Здесь показаны различия между двумя версиями данной страницы.
| Следующая версия | Предыдущая версия | ||
|
mysql:when_to_order_before_group [2021/07/09 22:24] werwolf создано |
mysql:when_to_order_before_group [2023/01/12 12:18] (текущий) |
||
|---|---|---|---|
| Строка 4: | Строка 4: | ||
| ====Таблицы в транзакционном стиле==== | ====Таблицы в транзакционном стиле==== | ||
| + | Для того чтобы сортировать с использованием позднее группировки нам понадобится подзапрос который, создаст так называемую временную таблицу! | ||
| - | Я идентифицирую эти таблицы как таблицы, в которых есть несколько строк, представляющих похожие или повторяющиеся данные, с автоматически увеличивающимся первичным ключом, используемым для их различения. В некоторых примерах записывается идентификатор каждого пользователя, просматривающего статью; другой записывает билеты в кино и количество проданных товаров. Понимание того, когда элементы меняют состояние, и наличие исторического контекста обычно являются основными причинами создания подобных таблиц. | + | Временная таблица создается автоматически всякий раз, когда результаты запроса используются в другом запросе. Этот внутренний запрос называется подзапросом. Таким образом, результаты подзапроса (который автоматически станет временной таблицей) могут быть снова запрошены запросом непосредственно над ним.\\ |
| + | \\ | ||
| + | Используя приведенный выше запрос для создания отсортированной временной таблицы, окончательный запрос будет следующим:\\ | ||
| - | ====Последний или первый в группе==== | + | <code sql> |
| + | # MySQL Version <= 5.6 | ||
| + | SELECT | ||
| + | sorted_temp_table.hole, | ||
| + | sorted_temp_table.distance, | ||
| + | sorted_temp_table.date | ||
| + | FROM ( | ||
| + | SELECT | ||
| + | hole, | ||
| + | distance, | ||
| + | DATE(created_at) AS 'date' | ||
| + | FROM golf_games | ||
| + | ORDER BY | ||
| + | distance DESC, | ||
| + | hole, | ||
| + | DATE(created_at) | ||
| + | ) AS sorted_temp_table | ||
| + | GROUP BY sorted_temp_table.hole | ||
| + | </code> | ||
| - | Предположим, вы заядлый игрок в гольф, который часто посещает любимое поле для гольфа, и хотите определить, улучшается ли ваш удар со временем. Что ж, главная причина, по которой вам нравится это поле для гольфа, заключается в том, что в нем есть технологическая система, которая может записывать любое количество лунок, на котором вы находитесь, и то, как далеко вы ударили мячом, чтобы добраться до следующей лунки. Вы просите персонал предоставить вам дамп данных ваших игр, и они дают вам таблицу, которая выглядит следующим образом: | + | Чтобы использовать этот запрос в MySQL 5.7 и новее, вам потребуются небольшие изменения:\\ |
| + | <code sql> | ||
| + | SELECT | ||
| + | sorted_temp_table.hole, | ||
| + | ANY_VALUE(sorted_temp_table.distance) AS distance, | ||
| + | ANY_VALUE(sorted_temp_table.date) AS 'date' | ||
| + | FROM ( | ||
| + | SELECT | ||
| + | (@row_number := @row_number + 1) AS virtual_id, | ||
| + | hole, | ||
| + | distance, | ||
| + | DATE(created_at) AS 'date' | ||
| + | FROM golf_games, | ||
| + | (SELECT @row_number := 0) AS row_table | ||
| + | ORDER BY | ||
| + | distance DESC, | ||
| + | hole, | ||
| + | DATE(created_at) | ||
| + | ) AS sorted_temp_table | ||
| + | GROUP BY sorted_temp_table.hole | ||
| + | ORDER BY sorted_temp_table.hole | ||
| + | </code> | ||
| - | {{ :mysql:1-rmy_rkyokksb0pdzrh2oig.png?nolink |}} | + | В MySQL 8 это немного проще:\\ |
| + | <code sql> | ||
| + | # MySQL Version >= 8 | ||
| + | SELECT | ||
| + | sorted_temp_table.hole, | ||
| + | ANY_VALUE(sorted_temp_table.distance) AS distance, | ||
| + | ANY_VALUE(sorted_temp_table.date) AS 'date' | ||
| + | FROM ( | ||
| + | SELECT | ||
| + | ROW_NUMBER() OVER ( | ||
| + | PARTITION BY hole | ||
| + | ORDER BY | ||
| + | distance DESC, | ||
| + | hole, | ||
| + | DATE(created_at) | ||
| + | ) AS virtual_id, | ||
| + | hole, | ||
| + | distance, | ||
| + | DATE(created_at) AS 'date' | ||
| + | FROM golf_games | ||
| + | ) AS sorted_temp_table | ||
| + | GROUP BY sorted_temp_table.hole | ||
| + | ORDER BY sorted_temp_table.hole | ||
| + | </code> | ||
| - | ====Гипотетический дамп данных о игре в гольф==== | + | Важно создать столбец virtual_id для нашей отсортированной временной таблицы. Это позволяет MySQL понять, что это функционально зависимая таблица. Затем, когда MySQL приступит к свертыванию строк на основе нашей GROUP BY sorted_temp_table.hole, предоставленная нами функция ANY_VALUE скажет ему выбрать первую доступную строку для группы. |
| - | + | ||
| - | + | ||
| - | ^ID^Hole^Distance^Date^ | + | |
| - | |1|8|169 |08-21| | + | |
| - | |2|10|33 |08-05| | + | |
| - | |3|5|188 |08-02| | + | |
| - | |4|13|64 |08-17| | + | |
| - | |5|3|200 |08-02| | + | |
| - | |6|8|35 |08-21| | + | |
| - | |7|14|142 |08-01| | + | |
| - | |8|11|107 |08-05| | + | |
| - | |9|10|83 |08-03| | + | |
| - | |1|16|179 |08-11| | + | |
| - | |1|4|184 |08-24| | + | |
| - | |1|17|124 |08-16| | + | |
| - | |1|7|104 |08-08| | + | |
| - | |1|4|1 |08-28| | + | |
| - | |1|7|147 |08-18| | + | |
| - | |1|13|24 |08-06| | + | |
| - | |1|7|126 |08-24| | + | |
| - | |1|9|48 |08-15| | + | |
| - | |1|8|176 |08-22| | + | |
| - | |2|9|74 |08-30| | + | |
| - | + | ||
| - | <note> | + | |
| - | Я установил максимальное значение для Distance равным 200. Это потому, что я предполагаю, что в реальном мире на самом деле существуют максимальные физические расстояния между лунками (я, очевидно, никогда не играл в гольф). | + | |
| - | </note> | + | |