论表与表之间的关系--半连接改写

昨天听了落落的课,讲到了表与表之间的关系。

以下是我的测试案例:

##SQL改写范例–SQL1(1:N关系)

SELECT *
  FROM DEPARTMENTS D
 WHERE D.DEPARTMENT_ID IN (SELECT E.DEPARTMENT_ID FROM EMPLOYEES E);

查询表DEPARTMENTS(department_id)与表EMPLOYEES(department_id)之间的关系

select count(*),department_id from departments group by department_id;

COUNT(*)DEPARTMENT_ID
110
120
130
140
150
160
170
180
190
1100
1110
1120
1130
1140
1150
1160
1170
1180
1190
1200
1210
1220
1230
1240
1250
1260
1270
SELECT COUNT(*),DEPARTMENT_ID FROM EMPLOYEES GROUP BY DEPARTMENT_ID;
COUNT(*)DEPARTMENT_ID
6100
630
1
390
220
170
2110
4550
3480
140
560
110

所以可以得知表DEPARTMENTS(department_id)与表EMPLOYEES(department_id)之间关系为1 : N

所以以上SQL可以等价改写成以下形式:

SELECT D.*
  FROM DEPARTMENTS D,(SELECT DEPARTMENT_ID FROM EMPLOYEES E GROUP BY DEPARTMENT_ID) C
  WHERE D.DEPARTMENT_ID=C.DEPARTMENT_ID

##SQL改写范例–SQL2(N:1关系)

SELECT *
  FROM EMPLOYEES E
 WHERE E.DEPARTMENT_ID IN (SELECT D.DEPARTMENT_ID FROM DEPARTMENTS D);

由案例1可以得知:
表EMPLOYEES(department_id)与表DEPARTMENTS(department_id)之间的关系为N:1

所以以上SQL可以等价改写成以下形式:


SELECT E.*
  FROM EMPLOYEES E, DEPARTMENTS D
 WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID

##SQL改写范例–SQL3(N:N关系)
创建以下表,并插入数据:

CREATE TABLE EMP_TEST AS SELECT * FROM EMPLOYEES ;
INSERT INTO EMP_TEST SELECT * FROM EMP_TEST;
...
重复插入至3000多条数据后
commitCREATE TABLE DEPT_TEST AS SELECT * FROM DEPARTMENTS;
INSERT INTO DEPT_TEST SELECT * FROM DEPT_TEST;
...
重复插入至1700多条数据后
commit

现在对以下SQL改写:

SELECT COUNT(*)
  FROM EMP_TEST  E
 WHERE E.DEPARTMENT_ID IN (SELECT D.DEPARTMENT_ID FROM DEPT_TEST  D);

count(*)
-------
3392

由以上建表时语句可以得知,

表EMP_TEST (department_id)与表DEPT_TEST (department_id)之间的关系为N:N

错误改写:

 SELECT COUNT(*)
  FROM EMP_TEST E, DEPT_TEST D
 WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID;

count(*)
-------
434176

正确改写:

 SELECT COUNT(*)
   FROM EMP_TEST E,
        (SELECT DEPARTMENT_ID FROM DEPT_TEST D GROUP BY D.DEPARTMENT_ID) C
  WHERE E.DEPARTMENT_ID = C.DEPARTMENT_ID;

count(*)
-------
3392
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值