Как правильно выполнять сглаживание в коррелированном подзапросе

#mysql #sql

#mysql #sql

Вопрос:

Для следующего подзапроса:

 ;WITH results as (
    SELECT 'DAL' as team, 2010 as season, 7 as wins union
    SELECT 'DAL' as team, 2011 as season, 11 as wins union
    SELECT 'DAL' as team, 2012 as season, 11 as wins union
    SELECT 'NE' as team, 2012 as season, 15 as wins union
    SELECT 'DET' as team, 2010 as season, 6 as wins
)

SELECT team, wins, season,
    wins - (select max(wins) from results as r where r.season=results.season) difference_from_best_subquery
FROM results;
 

Каков правильный способ псевдонимирования результатов, чтобы было ясно, что вы хотите передать «это» значение в результаты? Вышеуказанное работает, но я надеюсь, что смогу сделать что-то более читаемое (для себя), например:

 SELET MAX(wins) FROM table WHERE wins=$this.wins
 

Каков наилучший подход к этому?

Ответ №1:

В MySQL 8 я бы просто использовал MAX как аналитическую функцию:

 SELECT team, wins, season,
    MAX(wins) OVER (PARTITION BY season) - wins AS diff_from_best
FROM results;
 

Другим способом избежать коррелированного подзапроса было бы использовать подход объединения к подзапросу, который находит максимальные выигрыши для каждого сезона:

 SELECT
    r1.team,
    r1.wins,
    r1.season,
    r2.max_wins - r1.wins AS diff_from_best
FROM results r1
INNER JOIN
(
    SELECT season, MAX(wins) AS max_wins
    FROM results
    GROUP BY season
) r2
    ON r2.season = r1.season;
 

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

1. спасибо за это. Всегда ли оконная функция предпочтительнее подзапроса, или возможно ли, что подзапрос может работать лучше?

2. Хороший вопрос. На самом деле лучший ответ здесь заключается в том, что, вероятно, наиболее важным является включение индекса (season, wins) , что ускорит либо подход к аналитическим функциям, либо коррелированный подзапрос, либо объединение. Все они, вероятно, будут иметь (несколько) похожие планы выполнения.