SQL 集合

集合操作符

当对两个数据集执行集合操作符时,应遵循以下规范:

  • 两个数据集必须有相同数目的列
  • 两个数据集中对应列的数据类型必须相同
mysql> SELECT 1 num, 'abc' str UNION SELECT 9 num, 'xyz' str;
+-----+-----+
| num | str |
+-----+-----+
|   1 | abc |
|   9 | xyz |
+-----+-----+

多个集合操作规则:

  • 在调用集合操作时,Intersect操作符比其它操作符具有更高优先级
  • 可以使用圆括号对多个查询进行封装,以明确执行次序 
(SELECT [...]
UNION ALL
SELECT [...])
INTERSECT
(SELECT [...]
EXCEPT
SELECT [...])
  • union

unionunion all可以连接多个数据集,区别在于union对连接后的集合排序并去除重复项,而union all保留重复项,使用union all得到的最终行数总是等于所要连接的各个集合行数之和。

下面符合语句中第一个查询获取分配到2号支行的所有柜员,第二个查询返回所有在第二支行开户的雇员,结果ID为10的雇员重复。

mysql> SELECT emp_id FROM employee WHERE assigned_branch_id=2 AND (title='Teller' OR title='Head Teller') 
    -> UNION ALL SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2;
+--------+
| emp_id |
+--------+
|     10 |
|     11 |
|     12 |
|     10 |
+--------+
mysql> SELECT emp_id FROM employee WHERE assigned_branch_id=2 AND (title='Teller' OR title='Head Teller') 
    -> UNION SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2;
+--------+
| emp_id |
+--------+
|     10 |
|     11 |
|     12 |
+--------+
  • intersect

intersect运算符是一个集合运算符,它只返回两个查询或更多查询的交集。

oracle> SELECT emp_id FROM employee WHERE assigned_branch_id=2 AND (title='Teller' OR title='Head Teller') 
    -> INTERSECT SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2;
+--------+
| emp_id |
+--------+
|     10 |
+--------+

MySQL不支持INTERSECT操作符。 但是我们可以模拟INTERSECT操作符。

  • 使用DISTINCT运算符和INNER JOIN子句模拟MySQL INTERSECT运算符
mysql> SELECT DISTINCT e.emp_id FROM employee e INNER JOIN account a ON a.open_emp_id=e.emp_id 
    -> WHERE e.assigned_branch_id=2 AND a.open_branch_id=2 AND (e.title='Teller' OR e.title='Head Teller');
+--------+
| emp_id |
+--------+
|     10 |
+--------+
1 row in set (0.00 sec)
  • 使用IN运算符和子查询模拟MySQL INTERSECT运算符
mysql> SELECT DISTINCT emp_id FROM employee WHERE emp_id IN 
    -> (SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2);
+--------+
| emp_id |
+--------+
|     10 |
+--------+
1 row in set (0.02 sec)

mysql> SELECT DISTINCT emp_id FROM employee WHERE emp_id IN 
    -> (SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2)
    -> AND assigned_branch_id=2 AND (title='Teller' OR title='Head Teller');
+--------+
| emp_id |
+--------+
|     10 |
+--------+
1 row in set (0.00 sec)
  • except

except操作符返回第一个表减去与第二表重合元素后剩下的部分。

oracle> SELECT emp_id FROM employee WHERE assigned_branch_id=2 AND (title='Teller' OR title='Head Teller') 
    -> EXCEPT SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2;
+--------+
| emp_id |
+--------+
|     11 |
|     12 |
+--------+
  • 使用IN运算符和子查询模拟MySQL EXCEPT运算符
mysql> SELECT DISTINCT emp_id FROM employee WHERE emp_id NOT IN 
    -> (SELECT DISTINCT open_emp_id FROM account WHERE open_branch_id=2) AND assigned_branch_id=2;
+--------+
| emp_id |
+--------+
|     11 |
|     12 |
+--------+
2 rows in set (0.00 sec)

 

猜你喜欢

转载自blog.csdn.net/linshuo1994/article/details/84560002