SQL: группировка без использования агрегатной функции - PullRequest
0 голосов
/ 11 сентября 2018

У меня следующий запрос SQL:

select * from my_table

тогда возвращаемые результаты выглядят так:

my_id    field_1    field_2   ...
 1         ...       ...
 1         ...       ... 
 1         ...       ...
 2
 3
 3

Я хочу сохранить только одну запись на my_id, возможно, взять запись с минимальным значением в field_2

Поэтому я ожидаю, что следующий запрос завершится неудачно, потому что я не поставил нужную функцию агрегирования после select:

select * from my_table group by my_id order by my_id

Однако запрос прошел, и в возвращенной таблице нет дубликатов my_id. Поэтому мне интересно, есть ли метод по умолчанию, который использует SQL, если я не указал функцию агрегирования до group by?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Я ожидаю, что следующий запрос не будет выполнен, потому что я не поставил желаемая агрегация ..

К сожалению, некоторые реализации SQL позволяют GROUP BY без агрегатной функции 1 .

В этом случае результат «не определен / реализация не определена» - см. Конкретную документацию по реализации, чтобы узнать, предоставляет ли она какие-либо гарантии. То есть, хотя все еще гарантируется, что столбец my_id уникален, значения из любой строки могут быть возвращены для других полей вывода .

(Очевидно, что если бы my_id был ключом / ключом-кандидатом - но это не так в данном случае - тогда это не имеет значения, поскольку может быть выбрана только одна строка * ..)

Для повышения совместимости и предсказуемых результатов, использовать агрегатную функцию для каждого поля, которое не охватывается GROUP BY - , даже если конкретный SQL / СУБД не предписывает и не «требует» использования агрегатов.


1 Хотя исходный запрос «принят» в MySQL ( в зависимости от ONLY_FULL_GROUP_BY ), и PostgreSQL, и SQL Server будут иметь отклоненные исходный запрос " как и ожидалось ".

0 голосов
/ 11 сентября 2018

Вы можете использовать коррелированный подзапрос:

select t.*
from my_table t
where t.field2 = (select min(t2.field2)
                  from my_table t2
                  where t2.my_id = t.my_id
                 );
...