SQL语法(DQL):SELECT 多表查询之Join与Union

发布于:2024-07-10 ⋅ 阅读:(147) ⋅ 点赞:(0)

1、多表查询:Join

  • 功能:用于根据两张表的关系,实现两张表列的拼接
  • 场景

    • 用于实现列的合并,结果中的列来自于多张表。

    • 实现两份数据集合操作【交集、差集、全集】

  • 语法:

  • SELECT 
    	A.*,
    	B.*,
    	…
    FROM A 
    [ INNER | OUTER ] JOIN B [ ON A.col = B.col ]
    [ INNER | OUTER ] JOIN C [ ON A.col = C.col ]
    ……
  • 内连接 inner join

    • 功能:用于根据关联条件,保留两边都存在的数据
    • 语法:INNER JOIN,其中 INNER 可以省略
    • -- 方式一:
          from A inner join B
      -- 方式二:
          from A, B
    • 场景:两边都有,结果就有,取两份数据的交集
    • 示例:
    • -- 查询所有成绩小于60分的学生信息
      
      SELECT
      	student.* 
      FROM
      	student
      	INNER JOIN 
      	    ( 
      	        SELECT s_id,
      	               MAX( s_score ) max 
      	        FROM score 
      	        GROUP BY s_id 
      	        HAVING max < 60 ) m 
      	ON student.s_id = m.s_id
      ;
    • 注意:在使用内连接时,可以省略 inner 关键词,关联条件也可以省略,如果省略了关联条件,就构建了笛卡尔积【交叉连接】,我们把这种没有关联条件的join,叫做cross join,结果是两张表的无差别关联,数据有A * B 条,一般不建议使用
  • 外连接 outer join

    • 功能:用于根据关联条件,保留 左边的 或者 右边的 或者 全部的 数据
    • 语法:outer关键词可以省略

    • left outer join:左连接,保留左边所有的数据行,如果右边没有与之对应的行,则右边表的字段为null
      
      right outer join:右连接,保留右边所有的数据行,如果左边没有与之对应的行,则左边表的字段为null
    • 场景:

      • left join:左边有,结果就有,用于返回左表的所有数据并带上右表的列
      • right join:右边有,结果就有,用于返回右表的所有数据并带上左表的列
      • 注意任意一边没有对应的值,就会为null

    • 示例:

    • -- 查询所有学生的学号、姓名、选课数、总成绩
      
      SELECT
      	st.s_id,
      	st.s_name,
      	COUNT( sc.c_id ),
      	SUM( IFNULL( sc.s_score, 0 ) ) totalscore
      FROM
      	student st
      	LEFT JOIN score sc ON st.s_id = sc.s_id
      GROUP BY
      	st.s_id
      
  • 自连接

    • 自己与自己连接就叫做自连接,即:A JOIN A
    • 语法
    • SELECT …… FROM A as a JOIN A as b ON 条件 
    • 示例:
    • -- 查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号和成绩
      
      SELECT
      	student.*,
      	m.score1,
      	m.score2 
      FROM
      	student
      	INNER JOIN (
      SELECT
      	s1.s_id,
      	s1.s_score score1,
      	s2.s_score score2 
      FROM
      	score s1
      	JOIN score s2 ON s1.s_id = s2.s_id 
      	AND s1.c_id = 1 
      	AND s2.c_id = 2 
      	AND s1.s_score > s2.s_score 
      	) m ON student.s_id = m.s_id
      
    • 上述示例使用自连接就可以很方便的将同一个学生的‘01’课程和‘02’课程进行比较。

2、多表查询:Union

  • 功能:实现对两张数据表的行的合并
  • 场景:将两份用户的数据进行合并
  • 语法:
  • -- union:会去重
    select …… union select ……
    
    -- union all:不会去重
    select …… union all select ……
  • 注意:要求两份数据的字段个数必须一致
  • 实现:
  • -- 实现union
    select * from tb_user_union1
    union
    select * from tb_user_union2;
    
    -- 实现union并排序
    ( select * from tb_user_union1)
    union
    ( select * from tb_user_union2)
    order by u_id desc
    ;
    
    
    -- 实现union all
    select * from tb_user_union1
    union all
    select * from tb_user_union2;

3、去重distinct

  • 问题:如果数据中本来就有重复的,如何实现数据的去重?

  • 解决:distinct去重

  • 功能:用于对表中的数据实现去重

  • 场景:1、直接在select语句中对字段进行去重。2、在聚合的时候对每组内部进行去重:count(distinct col)

  • 语法:

  • select distinct 字段 from 表
  • 实现:
  • -- 建表
    drop table if exists tb_user_distinct;
    create table if not exists tb_user_distinct
    as
    select 1 as id , '张三' as name
    union all
    select 2 as id , '李四' as name
    union all
    select 1 as id , '张三' as name
    union all
    select 2 as id , '王五' as name
    ;
    
    -- 查询
    select * from tb_user_distinct;
    
    -- 去重id
    select distinct id from tb_user_distinct;
    
    -- 去重name
    select distinct name from tb_user_distinct;
    
    -- 去重多列
    select distinct id, name from tb_user_distinct;
    
    -- 去重行
    select distinct * from tb_user_distinct;
  • 小结:MySQL去重的方式哪有几种?
  • 方案一:distinct
    方案二:union
    方案三:group by:分组,一组只返回一条
    方案四:窗口函数
    方案五:聚合函数


网站公告

今日签到

点亮在社区的每一天
去签到