MySQL: Выбор строк при первом вхождении каждого уникального значения
Описание проблемы
У меня есть следующая таблица, в которой интересующая нас колонка — это cid
:
+-----+-------+-------+-------+---------------------+--------------+
| cid | pid | rid | clink | time | snippet |
+-----+-------+-------+-------+---------------------+--------------+
| 155 | 11222 | 1499 | 1137 | 2012-08-22 03:05:06 | hi |
| 138 | 11222 | 241 | 1136 | 2012-08-21 05:25:00 | again |
| 138 | 11222 | 241 | 1135 | 2012-08-21 05:16:40 | hi |
| 155 | 11222 | 1499 | 1134 | 2012-08-21 05:11:00 | hi cute |
| 140 | 11222 | 11223 | 1133 | 2012-08-21 05:05:18 | hi |
| ... | ... | ... | ... | ... | ... |
+-----+-------+-------+-------+---------------------+--------------+
Мне нужно извлечь только первое вхождение каждого уникального cid
. В результате должна получиться таблица, которая будет выглядеть следующим образом:
+-----+-------+-------+-------+---------------------+--------------+
| cid | pid | rid | clink | time | snippet |
+-----+-------+-------+-------+---------------------+--------------+
| 155 | 11222 | 1499 | 1137 | 2012-08-22 03:05:06 | hi |
| 138 | 11222 | 241 | 1136 | 2012-08-21 05:25:00 | again |
| 140 | 11222 | 11223 | 1133 | 2012-08-21 05:05:18 | hi |
| 154 | 11222 | 565 | 1132 | 2012-08-21 05:04:47 | 7 |
| 153 | 11222 | 272 | 1131 | 2012-08-21 05:04:41 | 6 |
| ... | ... | ... | ... | ... | ... |
+-----+-------+-------+-------+---------------------+--------------+
Как я могу написать запрос, чтобы получить только первые вхождения для каждого cid
?
4 ответ(ов)
В MySQL есть "хака" для этой задачи:
SELECT *
FROM mytable
GROUP BY cid;
Это всё, что вам нужно, потому что в MySQL разрешено не агрегировать столбцы, которые не входят в GROUP BY (в других СУБД это вызвало бы ошибку синтаксиса). В этом случае MySQL вернет только первое совпадение для каждого значения в GROUP BY. Однако стоит отметить, что это не гарантирует, каким образом выбирается "первое" совпадение — это будет зависеть от порядка чтения строк.
Если вы хотите получить определённое первое совпадение, сначала нужно отсортировать строки, а затем применить "хака" с группировкой:
SELECT *
FROM (
-- сортируем по столбцу "time" в порядке убывания, чтобы получить "самую последнюю" строку
SELECT * FROM mytable ORDER BY time DESC
) x
GROUP BY cid;
Таким образом, вы сможете получить именно ту строку, которая вам нужна!
Вы можете использовать следующий SQL-запрос, чтобы получить записи с минимальным значением времени для каждой группы:
SELECT *
FROM tableName a
INNER JOIN (
SELECT cid, MIN(`time`) AS MinTime
FROM tableName
GROUP BY cid
) b
ON a.cid = b.cid AND a.time = b.MinTime
В этом запросе мы сначала создаем подзапрос, который выбирает cid
и минимальное время (MinTime
) для каждой группы cid
. Затем мы выполняем внутреннее соединение с основной таблицей (tableName
), используя условия на совпадение cid
и значения времени. Это позволит вам получить все строки из оригинальной таблицы, которые имеют минимальное время для каждого cid
.
Я понимаю, что это старая тема, но у меня возникла проблема с тем, что предложенное решение возвращает только столбцы, в которых более одного вхождения.
Вот что сработало для меня:
SELECT cid, pid, rid, clink, MAX(time), snippet
FROM mytable
GROUP BY cid
Такой запрос позволяет получить столбцы, которые мне нужны, включая MAX(time)
, и группирует результаты по колонке cid
. Надеюсь, это поможет и другим с подобной задачей!
Вы можете использовать фильтрующее соединение:
SELECT *
FROM (
SELECT cid,
MIN(time) AS min_time
FROM YourTable
GROUP BY cid
) AS filter
JOIN YourTable AS yt
ON filter.cid = yt.cid
AND filter.min_time = yt.time
Этот запрос сначала создает подзапрос, который выбирает минимальное время для каждого cid
, а затем выполняет соединение с основной таблицей YourTable
, чтобы получить все соответствующие записи.
SQL: выбрать только строки с максимальным значением в столбце
Когда использовать одинарные кавычки, двойные кавычки и обратные кавычки в MySQL
Удаление с использованием JOIN в MySQL
MySQL 1062 - Дубликат значения '0' для ключа 'PRIMARY'
java.sql.SQLException: Не найден подходящий драйвер для jdbc:mysql://localhost:3306/dbname