Уникальные идентификаторы? Да! Уникальные идентификаторы!
Один из лучших способов разработки базы данных MySQL - это есть каждый id
AUTOINCREMENT
(Источник MySQL.com). Это дает множество преимуществ, которых здесь невозможно описать. Проблема с вопросом в том, что в его примере есть повторяющиеся идентификаторы. Это игнорирует эти огромные преимущества уникальных идентификаторов и в то же время сбивает с толку тех, кто уже знаком с этим.
Самое чистое решение
DB Fiddle
Новые версии MySQL поставляются с ONLY_FULL_GROUP_BY
включенным по умолчанию, и многие из решений здесь терпят неудачу при тестировании с этим условием.
Даже в этом случае мы можем просто выбрать DISTINCT
someuniquefield, MAX(
whateverotherfieldtoselect )
, (
* somethirdfield )
и т. Д. И не беспокоиться о том, чтобы понять результат или как работает запрос:
SELECT DISTINCT t1.id, MAX(t1.rev), MAX(t2.content)
FROM Table1 AS t1
JOIN Table1 AS t2 ON t2.id = t1.id AND t2.rev = (
SELECT MAX(rev) FROM Table1 t3 WHERE t3.id = t1.id
)
GROUP BY t1.id;
SELECT DISTINCT Table1.id, max(Table1.rev), max(Table2.content)
: Вернуть DISTINCT
какое-то поле, MAX()
какое-то другое поле, последнее MAX()
является избыточным, потому что я знаю, что это всего одна строка, но она требуется по запросу.
FROM Employee
: поиск по таблице.
JOIN Table1 AS Table2 ON Table2.rev = Table1.rev
: Присоединяйтесь ко второй таблице к первой, потому что нам нужно получить комментарий max (table1.rev).
GROUP BY Table1.id
: Принудительно использовать сортированную по верхнему краю строку Salary каждого сотрудника как возвращаемый результат.
Обратите внимание, что, поскольку контент был ... в вопросе OP, нет возможности проверить, что это работает. Итак, я изменил это на ..a, ..b, так что теперь мы действительно можем видеть, что результаты верны:
id max(Table1.rev) max(Table2.content)
1 3 ..d
2 1 ..b
Почему он чистый? DISTINCT()
, MAX()
и т. д. - все они прекрасно используют индексы MySQL. Это будет быстрее. Или это будет намного быстрее, если у вас есть индексирование, и вы сравните его с запросом, который просматривает все строки.
Исходное решение
Если ONLY_FULL_GROUP_BY
отключен, мы можем по-прежнему использовать GROUP BY
, но тогда мы используем его только для зарплаты, а не для идентификатора:
SELECT *
FROM
(SELECT *
FROM Employee
ORDER BY Salary DESC)
AS employeesub
GROUP BY employeesub.Salary;
SELECT *
: вернуть все поля.
FROM Employee
: поиск по таблице.
(SELECT *...)
подзапрос: вернуть всех людей, отсортированных по зарплате.
GROUP BY employeesub.Salary
: принудительно использовать сортированную по верхнему краю строку Salary каждого сотрудника как возвращаемый результат.
Решение Unique-Row
Обратите внимание на определение реляционной базы данных: каждая строка в таблице имеет свой уникальный ключ. Это означало бы, что в примере вопроса id должен быть уникальным, и в этом случае мы можем просто сделать:
SELECT *
FROM Employee
WHERE Employee.id = 12345
ORDER BY Employee.Salary DESC
LIMIT 1
Надеюсь, это решение, которое решит проблему и поможет всем лучше понять, что происходит в БД.
person
HoldOffHunger
schedule
14.09.2016
content
для строки? - person Mark Byers   schedule 12.10.2011SELECT DISTINCT ON .... ORDER BY "UserId", "Deals".position;
работал лучше - person Muhammad Umer   schedule 07.03.2018AUTO_INCREMENT
с двумя полями - dba.stackexchange.com/q/35449. Это делает это очень нестандартным; Если я не могу увеличить его позицию, насколько полезна уникальная позиция? - person HoldOffHunger   schedule 05.03.2020