子查询无处不在!以及最佳实践!

SQL 中的数据处理

Mona Khalil

Data Scientist, Greenhouse Software

想用多少子查询都行……

  • 可在 SELECTFROMWHERE 中包含多个子查询
SELECT 
    s.stage,
    ROUND(s.avg_goals,2) AS avg_goal,
    (SELECT AVG(home_goal + away_goal)
     FROM match WHERE season = '2013/2014') AS overall_avg
FROM 
    (SELECT
         stage,
         AVG(home_goal + away_goal) AS avg_goals
     FROM match
     WHERE season = '2013/2014'
     GROUP BY stage) AS s
WHERE 
    s.avg_goals > (SELECT AVG(home_goal + away_goal) 
                   FROM match WHERE season = '2013/2014');
SQL 中的数据处理

格式化你的查询

  • 对齐 SELECTFROMWHEREGROUP BY
SELECT
    col1,
    col2,
    col3
FROM table1
WHERE col1 = 2;
SQL 中的数据处理

给查询加注释

/* 此查询筛选 col1 = 2,
且仅选择 table1 的数据 */
SELECT
    col1,
    col2,
    col3
FROM table1
WHERE col1 = 2;
SQL 中的数据处理

给查询加注释

SELECT
    col1,
    col2,
    col3
FROM table1 -- 此表有 10,000 行
WHERE col1 = 2; -- WHERE 过滤值为 2
SQL 中的数据处理

缩进你的查询

  • 子查询要缩进!
SELECT
    col1,
    col2,
    col3
FROM table1
WHERE col1 IN
        (SELECT id
         FROM table2
         WHERE year = 1991);
SQL 中的数据处理

缩进你的查询

SELECT 
  date, 
  hometeam_id, 
  awayteam_id,
  CASE WHEN hometeam_id = 8455 AND home_goal > away_goal 
            THEN 'Chelsea home win'
       WHEN awayteam_id = 8455 AND home_goal < away_goal
            THEN 'Chelsea away win'
       WHEN hometeam_id = 8455 AND home_goal < away_goal
            THEN 'Chelsea home loss'
       WHEN awayteam_id = 8455 AND home_goal > away_goal
            THEN 'Chelsea away loss'
       WHEN (hometeam_id = 8455 OR awayteam_id = 8455) 
            AND home_goal = away_goal THEN 'Chelsea Tie'
       END AS outcome
FROM match
WHERE hometeam_id = 8455 OR awayteam_id = 8455;

Holywell 的 SQL 风格指南

SQL 中的数据处理

这个子查询有必要吗?

  • 子查询会消耗计算资源

    • 你的数据库多大?
    • 被查询的表多大?
  • 这个子查询真的必要吗?

SQL 中的数据处理

为每个子查询正确加筛选!

  • 注意你的筛选条件!
SELECT 
    s.stage,
    ROUND(s.avg_goals,2) AS avg_goal,
    (SELECT AVG(home_goal + away_goal)
     FROM match WHERE season = '2013/2014') AS overall_avg
FROM 
    (SELECT
         stage,
         AVG(home_goal + away_goal) AS avg_goals
     FROM match
     WHERE season = '2013/2014'
     GROUP BY stage) AS s
WHERE 
    s.avg_goals > (SELECT AVG(home_goal + away_goal) 
                   FROM match WHERE season = '2013/2014');
SQL 中的数据处理

Passons à la pratique !

SQL 中的数据处理

Preparing Video For Download...