Фон
Мой типичный вариант использования:
# Table
id category dataUID
---------------------------
0 A (NULL)
1 B (NULL)
2 C text1
3 C text1
4 D text2
5 D text3
# Query
SELECT MAX(`id`) AS `id` FROM `table`
GROUP BY `category`
Это хорошо; он удалит все «дублирующиеся категории» в наборе записей, над которым работает, и даст мне «самый высокий» идентификатор для каждой категории.
Затем я могу использовать этот идентификатор, чтобы снова извлечь все данные:
# Query
SELECT * FROM `table` JOIN (
SELECT MAX(`id`) AS `id` FROM `table`
GROUP BY `category`
) _ USING(`id`)
# Result
id category dataUID
---------------------------
0 A (NULL)
1 B (NULL)
3 C text1
5 D text3
Обратите внимание, что это не так же, как:
SELECT MAX(`id`) AS `id`, `category`, `dataUID` FROM `table`
GROUP BY `category`
За документацию :
В стандартном SQL запрос, включающий предложение GROUP BY, не может ссылаться
на неагрегированные столбцы в списке выбора, которые не названы в
Предложение GROUP BY. Например, этот запрос недопустим в стандартном SQL
потому что имя столбца в списке выбора не отображается в
GROUP BY:
SELECT o.custid, c.name, MAX(o.payment) FROM orders AS o, customers
AS c WHERE o.custid = c.custid GROUP BY o.custid;
Чтобы запрос был законным, столбец имени должен быть опущен
выберите список или имя в предложении GROUP BY.
MySQL расширяет использование GROUP BY, так что список выбора может ссылаться на
неагрегированные столбцы, не указанные в предложении GROUP BY. Это означает
что предыдущий запрос допустим в MySQL. Вы можете использовать эту функцию
чтобы получить лучшую производительность, избегая ненужной сортировки столбцов и
группировка. Однако это полезно, прежде всего, когда все значения в каждом
Неагрегированные столбцы, не названные в GROUP BY, одинаковы для каждого
группа.
[..]
В этом расширении предполагается, что у несгруппированных столбцов будут одинаковые групповые значения. В противном случае результат будет неопределенным.
Так что я бы получил неопределенное значение для dataUID
& mdash; например, text2
или text3
для результата с id
5
.
На самом деле это проблема для других полей в моем реальном случае; как это происходит, особенно для столбца dataUID
, обычно мне все равно, какое значение я получу.
Проблема
Однако!
Если какая-либо из строк для данного category
имеет NULL
dataUID
, и хотя бы еще одна строка имеет не-1061 * dataUID
, я бы хотел, чтобы MAX
игнорировал NULL
единицы.
Итак:
id category dataUID
---------------------------
4 D text2
5 D (NULL)
В настоящее время, поскольку я выбираю строку с максимальным идентификатором, я получаю:
5 D (NULL)
Но, поскольку dataUID
равен NULL
, вместо этого я хочу:
4 D text2
Как я могу получить это? Как добавить условную логику к использованию агрегата MAX
?
Я подумал о том, чтобы, возможно, передать MAX
кортеж и потом извлечь из него id
:
GET_SECOND_PART_SOMEHOW(MAX((IF(`dataUID` NOT NULL, 1, 0), `id`))) AS `id`
Но я не думаю, что MAX
будет принимать произвольные выражения, подобные этому, не говоря уже о кортежах, и я не знаю, как бы я извлек вторую часть кортежа после факта.