Почему я получаю разные результаты в этих 2 SQL-запросах? Использование только AVG против при использовании over()

#sql #group-by #window-functions #querying

Вопрос:

С помощью AVG() :

 SELECT
    c.id,
    c.name,
    m.season,
    m.home_goal,
    m.away_goal,
    AVG(m.home_goal   m.away_goal) AS overall_avg
FROM 
    country AS c
LEFT JOIN 
    match AS m ON c.id = m.country_id
WHERE 
    name = 'Belgium'
GROUP BY 
    c.id, m.season, m.home_goal, m.away_goal
 
 

С помощью OVER() :

 SELECT
    c.id,
    c.name,
    m.season,
    m.home_goal,
    m.away_goal,
    AVG(m.home_goal   m.away_goal) OVER() AS overall_avg
FROM 
    country AS c
LEFT JOIN 
    match AS m ON c.id = m.country_id 
 

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

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

1. Пожалуйста, отметьте RDMS.

Ответ №1:

В вашем первом GROUP BY запросе AVG(m.home_goal m.away_goal) есть агрегатная функция, которая вернет среднее значение для каждой группы. Во втором не GROUP BY запросе AVG(m.home_goal m.away_goal) OVER() есть оконная функция, которая возвращает среднее значение по всей таблице.

Ответ №2:

Игнорируя отсутствие where критериев в вашем втором запросе (просто ошибка в вашем вопросе?), они принципиально отличаются.

С помощью этого group by предложения результаты группируются по различным уникальным комбинациям сгруппированных столбцов, объединяя все похожие строки в одну, и для каждой из этих групп avg() -и любые другие агрегированные функции также — работают со строками в этих группах по отдельности.

Во втором запросе группировка строк не выполняется, поэтому возвращается каждая строка. Использование avg() функции с over предложением называется оконной функцией, где рассматриваемое окно (в основном диапазон строк) определяется предложением over; () означает, что окно представляет собой весь набор результатов, и каждая строка получает среднее значение по всем строкам.