MySQL-(联合查询-结果集合并)union和union all用法

1: 什么时候用union和union all ?

      我们经常会碰到这样的应用,两个表的数据按照一定的查询条件查询出来以后,需要将结果合并到一起显示出来,这个时候就需要用到union和union all关键字来实现这样的功能,union和union all的主要区别是union all是把结果集直接合并在一起,而union 是将union all后的结果镜像一次distinct,去除重复的记录后的结果。   

    看下面的例子:

查询一:

查询二:

两个结果集进行union all为(直接将两个查询结果集合并):

 两个结果集镜像union 运算结果为(两个结果集合并后进行去重/distinct):

 

当使用 UNION 时,MySQL 会把结果集中重复的记录删掉,而使用 UNION ALL ,MySQL 会把所有的记录返回,且效率高于 UNION。

总结: 在xwwd项目中由于还款计划表(tb_laon_repayment)数据量巨大(数量2000万),

查询一条借款的还款计划时候巨慢,当时为了解决查询慢问题就建立了一张还款计划

备份表(tb_loan_repayment_his),将还款计划表tb_loan_repayment中的已经结清

的借款的还款计划数据导出1000万到了还款计划备份表tb_loan_repayment_his中,

这样做解决了还款计划表tb_loan_repayment中数据过大导致查看借款loan详情时展示

查询该笔借款loan的还款计划查询卡死的情况。    后来由于项目需要需要查询备份表中的数据,

于是对内管查看借款详情接口进行了优化升级。 获取具体某一条还款计划的时候首先查询

还款计划表tb_laon_repayment如果没有再去查询还款计划备份表tb_loan_repayment_his.

同时“借款管理”菜单中是去分页查询所有还款计划,为了数据完整性,

这里就采用了union联合查询tb_loan_repayment,和tb_tb_repayment_his表。

 

其他练习:

student表:

-- ----------------------------

-- Table structure for `student`

-- ----------------------------

DROP TABLE IF EXISTS `student`;

CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `namevarchar(10) DEFAULT NULL,

  `age` tinyint(4) DEFAULT NULL,

  `classId` int(11) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of student

-- ----------------------------

INSERT INTO `student` VALUES ('1''s1''20''1');

INSERT INTO `student` VALUES ('2''s2''22''1');

INSERT INTO `student` VALUES ('3''s3''22''2');

INSERT INTO `student` VALUES ('4''s4''25''2');

teacher表:

-- ----------------------------

-- Table structure for `teacher`

-- ----------------------------

DROP TABLE IF EXISTS `teacher`;

CREATE TABLE `teacher` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `namevarchar(10) DEFAULT NULL,

  `age` tinyint(4) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of teacher

-- ----------------------------

INSERT INTO `teacher` VALUES ('1''t1''36');

INSERT INTO `teacher` VALUES ('2''t2''33');

INSERT INTO `teacher` VALUES ('3''s3''22');

查询数据如下:

mysql> SELECT FROM student;

+----+------+-----+---------+

| id | name | age | classId |

+----+------+-----+---------+

|  1 | s1   |  20 |       1 |

|  2 | s2   |  22 |       1 |

|  3 | s3   |  22 |       2 |

|  4 | s4   |  25 |       2 |

+----+------+-----+---------+

rows in set

 

mysql> SELECT FROM teacher;

+----+------+-----+

| id | name | age |

+----+------+-----+

|  1 | t1   |  36 |

|  2 | t2   |  33 |

|  3 | s3   |  22 |

+----+------+-----+

rows in set

使用 UNION的结果:

mysql> SELECT id, name, age FROM student

    -> UNION  -- 与UNION DISTINCT相同

    -> SELECT id, name, age FROM teacher;

+----+------+-----+

| id | name | age |

+----+------+-----+

|  1 | s1   |  20 |

|  2 | s2   |  22 |

|  3 | s3   |  22 |

|  4 | s4   |  25 |

|  1 | t1   |  36 |

|  2 | t2   |  33 |

+----+------+-----+

rows in set

使用 UNION ALL的结果:

mysql> SELECT id, name, age FROM student

    -> UNION ALL

    -> SELECT id, name, age FROM teacher;

+----+------+-----+

| id | name | age |

+----+------+-----+

|  1 | s1   |  20 |

|  2 | s2   |  22 |

|  3 | s3   |  22 |

|  4 | s4   |  25 |

|  1 | t1   |  36 |

|  2 | t2   |  33 |

|  3 | s3   |  22 |

+----+------+-----+

rows in set

其实联合查询跟字段的类型无关,只要求每个SELECT查询的字段数一样,能对应即可,如:

mysql> SELECT id, name, age FROM student -- 这里可以看出第一个SELECT语句中的字段名称被用作最后结果的字段名

    -> UNION

    -> SELECT age, name, id FROM teacher;

+----+------+-----+

| id | name | age |

+----+------+-----+

|  1 | s1   |  20 |

|  2 | s2   |  22 |

|  3 | s3   |  22 |

|  4 | s4   |  25 |

| 36 | t1   |   1 |

| 33 | t2   |   2 |

| 22 | s3   |   3 |

+----+------+-----+

rows in set

在联合查询中,当使用ORDER BY的时候,需要对SELECT语句添加括号,并且与LIMIT结合使用才生效,如:

mysql> (SELECT classId, id, name, age FROM student WHERE classId = 1 ORDER BY age DESC)

    -> UNION

    -> (SELECT classId, id, name, age FROM student WHERE classId = 2 ORDER BY age);

+---------+----+------+-----+

| classId | id | name | age |

+---------+----+------+-----+

|       1 |  1 | s1   |  20 |

|       1 |  2 | s2   |  22 |

|       2 |  3 | s3   |  22 |

|       2 |  4 | s4   |  25 |

+---------+----+------+-----+

rows in set

此时classId为1的学生并没有按照年龄进行降序,结合LIMIT后:

mysql> (SELECT classId, id, name, age FROM student WHERE classId = 1 ORDER BY age DESC LIMIT 2)

    -> UNION

    -> (SELECT classId, id, name, age FROM student WHERE classId = 2 ORDER BY age);

+---------+----+------+-----+

| classId | id | name | age |

+---------+----+------+-----+

|       1 |  2 | s2   |  22 |

|       1 |  1 | s1   |  20 |

|       2 |  3 | s3   |  22 |

|       2 |  4 | s4   |  25 |

+---------+----+------+-----+

rows in set

转载链接:https://www.cnblogs.com/ganbo/p/10803786.html

https://www.cnblogs.com/huangminwen/p/9261298.html

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值