公用表表达式(Common Table Expression)

什么是CTE?

WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。是为了让SQL语句的可读性更高些。

特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可。如果WITH AS短语所定义的表名被调用两次以上,则优化器会自动将WITH AS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将WITH AS短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。

WITH AS的注意事项

  1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE
with 
cr as 
( 
select CountryRegionCode from person.CountryRegion where Name like 'C%' 
) 
select * from person.CountryRegion -- 应将这条SQL语句去掉 
-- 使用CTE的SQL语句应紧跟在相关的CTE后面 -- 
select * from person.StateProvince where CountryRegionCode in (select * from cr) 
-- Set up your CTE
WITH match_list AS (
    SELECT 
  		country_id, 
  		id
    FROM match
    WHERE (home_goal + away_goal) >= 10)
-- CTE完成,下面是使用match_list的SQL语句
SELECT
    l.name AS league,
    COUNT(match_list.id) AS matches
FROM league AS l
-- Left Join CTE表
LEFT JOIN match_list ON l.id = match_list.country_id
GROUP BY l.name;
  1. CTE中可以使用的语句

2.1 JOIN

WITH match_list AS (
  -- Select the league name, date, home, and away goals
    SELECT 
  		l.name AS league, 
     	m.date, 
  		m.home_goal, 
  		m.away_goal,
       (m.home_goal + m.away_goal) AS total_goals
    FROM match AS m
    LEFT JOIN league as l ON m.country_id = l.id)
  1. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示
-- Create your home team CTE 第一个CTE
WITH home AS (
    -- Select the match id and team long name
    SELECT m.id, t.team_long_name 
    FROM match AS m
    LEFT JOIN team AS t ON m.hometeam_id = t.team_api_id),
    
-- Create your away team CTE. 第二个CTE(不需要WITH了)
away AS (
    -- Select the match id and team long name
    SELECT m.id, t.team_long_name
    FROM match AS m
    LEFT JOIN team AS t ON m.awayteam_id = t.team_api_id)
    
-- LEFT JOIN CTE表相关的SQL
SELECT 
	m.stage,
    m.date,
    home.team_long_name AS home_team,
    away.team_long_name AS away_team,
    m.home_goal,
    m.away_goal
FROM match AS m
-- Join the CTEs onto the match table
LEFT JOIN away ON m.id = away.id
LEFT JOIN home ON m.id = home.id
WHERE m.season = '2014/2015';

Reference:
https://www.jb51.net/article/30976.htm

你可能感兴趣的:(SQL)