MySQL從零開始 17-union合并查詢,表的自我復制
來源:轉載
發(fā)布時間:2018-07-03 17:44:20
閱讀量:1405
除了之前介紹的多表查詢,單表查詢之外,還可以使用union/union all集合操作符將多個多個select的執(zhí)行結果進行合并然后進行查詢。
?同樣,本次的測試用數據庫還是為scott數據庫,大家可以在我的GitHub進行scott數據庫創(chuàng)建腳本的下載。
1. 合并查詢
1.1 union
?union用于取得兩個結果集的并集。當使用該操作符時,會自動去掉結果集中的重復行。
mysql> select ename, sal, job from emp where sal>2500 union select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+| ename | sal | job |
+-------+---------+-----------+| JONES | 2975.00 | MANAGER |
| BLAKE | 2850.00 | MANAGER |
| SCOTT | 3000.00 | ANALYST |
| KING | 5000.00 | PRESIDENT |
| FORD | 3000.00 | ANALYST || CLARK | 2450.00 | MANAGER |
+-------+---------+-----------+6 rows in set (0.00 sec)123456789101112
1.2 union all
?顧名思義,union all用于取得兩個結果集的并集。當使用該操作符時,不會去掉結果集中的重復行。
?我們繼續(xù)使用例1的查詢場景。
mysql> select ename, sal, job from emp where sal>2500 union all select ename, sal, job from emp where job='MANAGER';
+-------+---------+-----------+| ename | sal | job |
+-------+---------+-----------+| JONES | 2975.00 | MANAGER |
| BLAKE | 2850.00 | MANAGER |
| SCOTT | 3000.00 | ANALYST |
| KING | 5000.00 | PRESIDENT |
| FORD | 3000.00 | ANALYST |
| JONES | 2975.00 | MANAGER |
| BLAKE | 2850.00 | MANAGER || CLARK | 2450.00 | MANAGER |
+-------+---------+-----------+8 rows in set (0.00 sec)1234567891011121314
?我們可以看到,union all查詢出來的結果要比union查詢出來的結果多兩行。
2. 自我復制
?自我復制又叫蠕蟲復制,是一種很有用的技巧,我們可以使用它進行大量測試數據的創(chuàng)建,復制表以及刪除表中重復記錄等場景下的應用。
2.1 大量測試數據的創(chuàng)建
?我們以scott數據庫的emp表為樣板。
mysql> select * from emp;
+--------+--------+-----------+------+---------------------+---------+---------+--------+| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+--------+-----------+------+---------------------+---------+---------+--------+| 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |
| 007499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 | 30 |
| 007521 | WARD | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250.00 | 500.00 | 30 |
| 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL | 20 |
| 007654 | MARTIN | SALESMAN | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 | 30 |
| 007698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL | 30 |
| 007782 | CLARK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL | 10 |
| 007788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL | 20 |
| 007839 | KING | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL | 10 |
| 007844 | TURNER | SALESMAN | 7698 | 1981-09-08 00:00:00 | 1500.00 | 0.00 | 30 |
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
| 007900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950.00 | NULL | 30 |
| 007902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL | 20 || 007934 | MILLER | CLERK | 7782 | 1982-01-23 00:00:00 | 1300.00 | NULL | 10 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+14 rows in set (0.00 sec)1234567891011121314151617181920
?我們可以看到,emp中有14條記錄,現在我們要讓它迅速擴充到100w以上的數據。


?我們可以看到,在不到1分鐘的時間里,我們就進行了100w以上條數據的插入,這也是數據庫的魅力之一。
2.2 復制表
?MySQL中沒有提供復制操作,所以我們可以使用自我復制,進行表的復制。
mysql> create table copy_dept like dept;
Query OK, 0 rows affected (0.23 sec)mysql> insert into copy_dept select * from dept;
Query OK, 4 rows affected (0.11 sec)
Records: 4 Duplicates: 0 Warnings: 0mysql> select * from copy_dept;
+--------+------------+----------+| deptno | dname | loc |
+--------+------------+----------+| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO || 40 | OPERATIONS | BOSTON |
+--------+------------+----------+4 rows in set (0.00 sec)1234567891011121314151617
2.3 刪除表中重復記錄
?刪除表中重復記錄也是實際場景之一,我們可以通過distinct配合select進行該操作。
-- 第一步:創(chuàng)建一個與原表表結構相同的空表,使用like關鍵字
mysql> create table temp like emp;
Query OK, 0 rows affected (0.06 sec)-- 第二步:使用distinct將重復元素過濾之后插入空表中
mysql> insert into temp select distinct * from emp;
Query OK, 14 rows affected (6.37 sec)
Records: 14 Duplicates: 0 Warnings: 0-- 第三步:刪除原表
mysql> drop table emp;
Query OK, 0 rows affected (0.01 sec)-- 第四步:將新建的表表名改為原表表名(貍貓換太子)
mysql> alter table temp rename emp;
Query OK, 0 rows affected (0.03 sec)mysql> select * from emp;
+--------+--------+-----------+------+---------------------+---------+---------+--------+| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+--------+-----------+------+---------------------+---------+---------+--------+| 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |
| 007499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 | 30 |
| 007521 | WARD | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250.00 | 500.00 | 30 |
| 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL | 20 |
| 007654 | MARTIN | SALESMAN | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 | 30 |
| 007698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL | 30 |
| 007782 | CLARK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450.00 | NULL | 10 |
| 007788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000.00 | NULL | 20 |
| 007839 | KING | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 | NULL | 10 |
| 007844 | TURNER | SALESMAN | 7698 | 1981-09-08 00:00:00 | 1500.00 | 0.00 | 30 |
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |
| 007900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950.00 | NULL | 30 |
| 007902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000.00 | NULL | 20 || 007934 | MILLER | CLERK | 7782 | 1982-01-23 00:00:00 | 1300.00 | NULL | 10 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+14 rows in set (0.01 sec)12345678910111213141516171819202122232425262728293031323334353637
?細心的同學們可以發(fā)現,100w條數據的數據庫刪除只花費了0.01秒,這是除了數據庫之外任何工具都不可能實現的,這也印證了數據庫是大量數據操作的必備之選。當然,由于我們在emp表中存在了大量的數據,所以在第二步使用distinct查找數據時花費了大量的時間,但這沒關系,在之后的章節(jié)中,這個問題會被解決。
原文地址https://blog.csdn.net/weixin_40739833/article/details/80851861