Подзапрос SQL и group by создают строки с одинаковыми значениями

#sql #sqlite #group-by #subquery

#sql #sqlite #группировка по #подзапрос

Вопрос:

В настоящее время у меня есть запрос, который работает нормально:

 SELECT teamID, yearID, AVG(HBP) as avgHBP FROM Batting 
GROUP BY teamID, yearID 
ORDER BY avgHBP DESC 
LIMIT 5;
  

Результат:

 | teamID | yearID | avgHBP |
|--------|--------|--------|
| BLN    | 1898   | 6.67   |
| BL3    | 1891   | 6.16   |
| BLN    | 1897   | 5.75   |
| BLN    | 1896   | 5.45   |
| BLN    | 1895   | 5.30   |
  

Однако, когда я пытаюсь добавить подзапрос (ни по какой другой причине, кроме как для изучения подзапросов),
Я понимаю это:

 SELECT teamID, (select yearID from Batting) as yearID2, AVG(HBP) as avgHBP FROM Batting 
GROUP BY teamID, yearID2 
ORDER BY avgHBP DESC 
LIMIT 5;
  

Результат:

 | teamID | yearID | avgHBP |
|--------|--------|--------|
| BLN    | 1871   | 4.44   |
| CL5    | 1871   | 3.93   |
| BL3    | 1871   | 3.86   |
| BFP    | 1871   | 3.69   |
| TL2    | 1871   | 3.55   |
  

где для всех столбцов учитывается только первый год (1871).

Это потому, что подзапрос применяется после group by ? Если бы я хотел добавить подзапрос, как правильно это сделать?

Ответ №1:

Подзапрос:

 select yearID from Batting
  

возвращает более 1 строки (фактически возвращает столько строк, сколько есть в таблице Batting ) и в любой другой СУБД этот запрос:

 SELECT teamID, (select yearID from Batting) as yearID2, AVG(HBP) as avgHBP 
FROM Batting 
GROUP BY teamID, yearID2
  

недопустимо.

Но SQLite разрешает это и возвращает только 1 строку, которая не определена.

Короче говоря, ваш запрос является недопустимым SQL, хотя он не выдает ошибку (только в SQLite).

Результаты, которые вы получаете, такие же, как если бы вы выполнили:

 SELECT teamID, AVG(HBP) as avgHBP 
FROM Batting 
GROUP BY teamID
  

с 1 дополнительным столбцом, который является неопределенным значением, возвращаемым yearID подзапросом.

На ваш вопрос:

Если бы я хотел добавить подзапрос, как правильно это сделать?

ответ заключается в том, что не существует общего правила добавления подзапроса.
Это зависит от требования.
Например, если вы использовали этот подзапрос:

 select max(yearID) from Batting
  

который возвращает только 1 строку, тогда у вас будет действительный запрос.

Комментарии:

1. Строго говоря, этот запрос неверен почти во всех СУБД, кроме SQLite и MySQL, потому что, согласно ANSII SQL, в запросе GROUP BY все выражения в предложении SELECT также должны быть перечислены в предложении GROUP BY . если thea не являются агрегатными функциями

2. @krokodilko результат подзапроса имеет псевдоним as yearID2 и используется в предложении GROUP BY . Так что проблема здесь не в этом.