加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Apache Flink 漫谈系列 - JOIN 算子

发布时间:2018-11-20 20:07:11 所属栏目:教程 来源:孙金城
导读:聊什么 在《Apache Flink 漫谈系列 - SQL概览》中我们介绍了JOIN算子的语义和基本的使用方式,介绍过程中大家发现Apache Flink在语法语义上是遵循ANSI-SQL标准的,那么再深思一下传统数据库为啥需要有JOIN算子呢?在实现原理上面Apache Flink内部实现和传统

如上结果我们得到9行=student(3) x course(3)。交叉联接一般会消耗较大的资源,也被很多用户质疑交叉联接存在的意义?(任何时候我们都有质疑的权利,同时也建议我们养成自己质疑自己“质疑”的习惯,就像小时候不理解父母的“废话”一样)。

我们以开篇的示例说明交叉联接的巧妙之一,开篇中我们的查询需求是:在学生表(学号,姓名,性别),课程表(课程号,课程名,学分)和成绩表(学号,课程号,分数)中查询所有学生的姓名,课程名和考试分数。开篇中的SQL语句得到的结果如下:

  1. mysql> SELECT 
  2.     ->   student.name, course.name, score 
  3.     -> FROM student JOIN  score ON student.no = score.s_no 
  4.     ->              JOIN course ON score.c_no = course.no; 
  5. +-------+-------+-------+ 
  6. | name  | name  | score | 
  7. +-------+-------+-------+ 
  8. | Sunny | Java  |    80 | 
  9. | Sunny | Blink |    98 | 
  10. | Sunny | Spark |    76 | 
  11. | Kevin | Java  |    78 | 
  12. | Kevin | Blink |    88 | 
  13. | Kevin | Spark |    68 | 
  14. +-------+-------+-------+ 
  15. 6 rows in set (0.00 sec) 

如上INNER JOIN的结果我们发现少了Tom同学的成绩,原因是Tom同学没有参加考试,在score表中没有Tom的成绩,但是我们可能希望虽然Tom没有参加考试但仍然希望Tom的成绩能够在查询结果中显示(成绩 0 分),面对这样的需求,我们怎么处理呢?交叉联接可以帮助我们:

  • 第一步 student和course 进行交叉联接:
    1. mysql> SELECT 
    2.     ->   stu.no, c.no, stu.name, c.name 
    3.     -> FROM student stu JOIN course c  笛卡尔积 
    4.     -> ORDER BY stu.no; -- 排序只是方便大家查看:) 
    5. +------+-----+-------+-------+ 
    6. | no   | no  | name  | name  | 
    7. +------+-----+-------+-------+ 
    8. | S001 | C03 | Sunny | Spark | 
    9. | S001 | C01 | Sunny | Java  | 
    10. | S001 | C02 | Sunny | Blink | 
    11. | S002 | C03 | Tom   | Spark | 
    12. | S002 | C01 | Tom   | Java  | 
    13. | S002 | C02 | Tom   | Blink | 
    14. | S003 | C02 | Kevin | Blink | 
    15. | S003 | C03 | Kevin | Spark | 
    16. | S003 | C01 | Kevin | Java  | 
    17. +------+-----+-------+-------+ 
    18. 9 rows in set (0.00 sec) 
  • 第二步 将交叉联接的结果与score表进行左外联接,如下:
    1. mysql> SELECT 
    2.     ->   stu.no, c.no, stu.name, c.name, 
    3.     ->    CASE 
    4.     ->     WHEN s.score IS NULL THEN 0 
    5.     ->     ELSE s.score 
    6.     ->   END AS score 
    7.     -> FROM student stu JOIN course c  -- 迪卡尔积 
    8.     -> LEFT JOIN score s ON sstu.no = s.s_no and c.no = s.c_no -- LEFT OUTER JOIN 
    9.     -> ORDER BY stu.no; -- 排序只是为了大家好看一点:) 
    10. +------+-----+-------+-------+-------+ 
    11. | no   | no  | name  | name  | score | 
    12. +------+-----+-------+-------+-------+ 
    13. | S001 | C03 | Sunny | Spark |    76 | 
    14. | S001 | C01 | Sunny | Java  |    80 | 
    15. | S001 | C02 | Sunny | Blink |    98 | 
    16. | S002 | C02 | Tom   | Blink |     0 | -- TOM 虽然没有参加考试,但是仍然看到他的信息 
    17. | S002 | C03 | Tom   | Spark |     0 | 
    18. | S002 | C01 | Tom   | Java  |     0 | 
    19. | S003 | C02 | Kevin | Blink |    88 | 
    20. | S003 | C03 | Kevin | Spark |    68 | 
    21. | S003 | C01 | Kevin | Java  |    78 | 
    22. +------+-----+-------+-------+-------+ 
    23. 9 rows in set (0.00 sec) 

经过CROSS JOIN帮我们将Tom的信息也查询出来了!(TOM 虽然没有参加考试,但是仍然看到他的信息)

2. INNER JOIN

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读