Какой лучший стандартный запрос sql для решения максимума в подгруппе - PullRequest
0 голосов
/ 12 июля 2020

Мне нужно сдать экзамен, и даже если с dbms (MySQL, чтобы быть более точным) запросы работают. Я спрашиваю себя, является ли это формально правильным и какая форма более формально правильна в следующей задаче, предполагая, что таблица выглядит следующим образом:

create table T(
    k integer primary key not null autoincrement,
    camp1 integer not null,
    camp2 integer not null);

Найдите строку для каждого значения camp2, которое имеет camp3, который является максимальное значение для подмножества: какое решение является правильным и если оба верны, какое формально является лучшим?

select * from T group by camp2 having camp3 = max(camp3);

или

select * from T b group by camp2 having camp3 = (select max(camp3) from T where T.camp2 = b.camp2);

1 Ответ

2 голосов
/ 12 июля 2020

Лучшим методом является коррелированный подзапрос:

select t.*
from t
where t.camp3 = (select max(t2.camp3) from t t2 where t2.camp2 = t.camp2);

В частности, он может использовать индекс на (camp2, camp3).

Ваши запросы должны генерировать синтаксические ошибки, потому что они неверно сформированные операторы SQL - использование select * с group by обычно не допускается. В частности, все выражения в select запроса агрегирования должны быть либо выражениями на ключах group by, либо аргументами для функций агрегирования. index!) в широком диапазоне баз данных, многие люди предпочитают row_number() вместо:

select t.*
from (select t.*, row_number() over (partition by camp2 order by camp3 desc) as seqnum
      from t
     ) t
where seqnum = 1;

Это также имеет хорошую производительность. А в более современных базах данных с массовым параллелизмом (например, Redshift, BigQuery, PrestoDB) он, вероятно, будет иметь лучшую производительность.

...