Over()开窗函数-Data camp练习

**

简单OVER()函数

**

不用OVER(),AVG()就是简单的聚合函数,会按照GROUP BY的方式来算每一个分区的AVG

SELECT 
	-- Select the id, country name, season, home, and away goals
	m.id, 
    c.name AS country, 
    m.season,
	m.home_goal,
	m.away_goal,
    -- Use a window to include the aggregate average in each row
	AVG(m.home_goal + m.away_goal)  AS overall_avg
FROM match AS m
LEFT JOIN country AS c ON m.country_id = c.id
GROUP BY m.id, c.name;

在这里插入图片描述

使用了OVER()以后

SELECT 
	-- Select the id, country name, season, home, and away goals
	m.id, 
    c.name AS country, 
    m.season,
	m.home_goal,
	m.away_goal,
    -- 此时没有加partition by的over(),分区就是整个DATASET,所以是overall_avg,相当于Tableau中的{AVG()}
	AVG(m.home_goal + m.away_goal) OVER() AS overall_avg
FROM match AS m
LEFT JOIN country AS c ON m.country_id = c.id;

在这里插入图片描述

RANK() OVER ()函数

SELECT 
	-- Select the league name and average goals scored
	l.name AS league,
    AVG(m.home_goal + m.away_goal) AS avg_goals,
    -- Rank each league according to the average goals 新增一列
    RANK() OVER(ORDER BY AVG(m.home_goal + m.away_goal)) AS league_rank
FROM league AS l
LEFT JOIN match AS m 
ON l.id = m.country_id
WHERE m.season = '2011/2012'
GROUP BY l.name
-- Order the query by the rank you created 还是要用新增的rank列来排序
ORDER BY league_rank;

在这里插入图片描述

SELECT 
	-- Select the league name and average goals scored
	name AS league,
    AVG(m.home_goal + m.away_goal) AS avg_goals,
    -- Rank leagues in descending order by average goals 用DESC实现倒序
    RANK() OVER (ORDER BY AVG(m.home_goal + m.away_goal) DESC) AS league_rank
FROM league AS l
LEFT JOIN match AS m 
ON l.id = m.country_id
WHERE m.season = '2011/2012'
GROUP BY l.name
-- Order the query by the rank you created
ORDER BY league_rank;

RANK()排序:

—rank()over(order by 列名 排序)的结果是不连续的,如果有4个人,其中有3个是并列第1名,那么最后的排序结果结果如:1 1 1 4

rank()over(order by TOTALEXAMSCORE desc) AS orderbyNum

—dense_rank()over(order by 列名 排序)的结果是连续的,如果有4个人,其中有3个是并列第1名, 那么最后的排序结果如:1 1 1 2

dense_rank()over(order by TOTALEXAMSCORE desc) AS orderbyNum

----rank () OVER (PARTITION BY 列名 ORDER BY 列名 排序)使用分区方式获取每门课程的最高分

rank () OVER (PARTITION BY coursename ORDER BY TOTALEXAMSCORE DESC) AS orderbynum

OVER() with Partition

  1. Partition by 1 column
SELECT
	date,
	season,
	home_goal,
	away_goal,
	CASE WHEN hometeam_id = 8673 THEN 'home' 
		 ELSE 'away' END AS warsaw_location,
    -- 以season为分区,同一个Season的AVG value一样
    AVG(home_goal) OVER(PARTITION BY season) AS season_homeavg,
    AVG(away_goal) OVER(PARTITION BY season) AS season_awayavg
FROM match
-- Filter the data set for Legia Warszawa matches only
WHERE 
	hometeam_id = 8673 
    OR awayteam_id = 8673
ORDER BY (home_goal + away_goal) DESC;

在这里插入图片描述

  1. Partition by MULTIPLE column
SELECT 
	date,
	season,
	home_goal,
	away_goal,
	CASE WHEN hometeam_id = 8673 THEN 'home' 
         ELSE 'away' END AS warsaw_location,
	-- 用season和month分区,同一个season,不同月份的AVG()就不一样了
    AVG(home_goal) OVER(PARTITION BY season, 
         	EXTRACT(MONTH FROM date)) AS season_mo_home,
    AVG(away_goal) OVER(PARTITION BY season, 
            EXTRACT(MONTH FROM date)) AS season_mo_away
FROM match
WHERE 
	hometeam_id = 8673 
    OR awayteam_id = 8673
ORDER BY (home_goal + away_goal) DESC;

在这里插入图片描述

OVER()和CTE结合

-- Set up the home team CTE 第一个CTE,找出所有M队当home team时的match
WITH home AS (
  SELECT m.id, t.team_long_name,
	  CASE WHEN m.home_goal > m.away_goal THEN 'Manchester United Win'
		   WHEN m.home_goal < m.away_goal THEN 'Manchester United Loss' 
  		   ELSE 'Tie' END AS outcome
  FROM match AS m
  LEFT JOIN team AS t ON m.hometeam_id = t.team_api_id),
-- Set up the away team CTE 第一个CTE,找出所有M队当away team时的match
away AS (
  SELECT m.id, t.team_long_name,
	  CASE WHEN m.home_goal > m.away_goal THEN 'Manchester United Loss'
		   WHEN m.home_goal < m.away_goal THEN 'Manchester United Win' 
  		   ELSE 'Tie' END AS outcome
  FROM match AS m
  LEFT JOIN team AS t ON m.awayteam_id = t.team_api_id)
-- Select columns and and rank the matches by date 找出所有M队输掉的比赛,按照date排序
SELECT DISTINCT
    m.date,
    home.team_long_name AS home_team,
    away.team_long_name AS away_team,
    m.home_goal, m.away_goal,
    RANK() OVER(ORDER BY date) as date_rank
-- Join the CTEs onto the match table 因为SELECT语句中有home, away两个CTE表的字段,所以不能是LEFT JOIN
FROM match AS m
INNER JOIN home ON m.id = home.id
INNER JOIN away ON m.id = away.id
WHERE m.season = '2014/2015'
      AND ((home.team_long_name = 'Manchester United' AND home.outcome = 'Manchester United Loss')
      OR (away.team_long_name = 'Manchester United' AND away.outcome = 'Manchester United Loss'));

第一个CTE(第二个类似)=》
在这里插入图片描述

最终结果=>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Cecilia_W422/article/details/88607383
今日推荐