【SQL】表连接 --半连接

半连接: 当一张表在另一张表找到匹配的记录之后,半连接(semi-jion)返回第一张表中的记录。与条件连接相反,即使在右节点中找到几条匹配的记录,左节点的表也只会返回一条记录。另外,右节点的表一条记录也不会返回。半连接通常使用IN  或 EXISTS 作为连接条件。下面是一个例子:

SQL> set linesize 999
SQL>  select d.deptno,d.dname,d.loc
  2  from scott.dept d
  3  where d.deptno IN  (select e.deptno from scott.emp e);

Execution Plan
----------------------------------------------------------
Plan hash value: 2365756639

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     3 |    69 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN SEMI             |         |     3 |    69 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     4 |    80 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PK_DEPT |     4 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT UNIQUE                |         |    14 |    42 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL         | EMP     |    14 |    42 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("D"."DEPTNO"="E"."DEPTNO")
       filter("D"."DEPTNO"="E"."DEPTNO")

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         11  consistent gets
          0  physical reads
          0  redo size
        750  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          3  rows processed

-------------------------------------   EXISTS  -----------------

SQL> select d.deptno,d.dname,d.loc
  2  from scott.dept d
  3  where EXISTS (select e.deptno from scott.emp e WHERE e.deptno = d.deptno);

Execution Plan
----------------------------------------------------------
Plan hash value: 2365756639

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     3 |    69 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN SEMI             |         |     3 |    69 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     4 |    80 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PK_DEPT |     4 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT UNIQUE                |         |    14 |    42 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL         | EMP     |    14 |    42 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("E"."DEPTNO"="D"."DEPTNO")
       filter("E"."DEPTNO"="D"."DEPTNO")

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         11  consistent gets
          0  physical reads
          0  redo size
        750  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          3  rows processed

附上半连接与条件连接的结果:

SQL> select d.deptno,d.dname,d.loc//半连接
  2  from scott.dept d
  3   where EXISTS (select e.deptno from scott.emp e WHERE e.deptno = d.deptno);

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO

SQL> select e.ename ,s.grade//条件连接
  2  from emp e,salgrade s
  3  where e.sal between s.losal and s.hisal;

ENAME           GRADE
---------- ----------
SMITH               1
JAMES               1
ADAMS               1
WARD                2
MARTIN              2
MILLER              2
TURNER              3
ALLEN               3
CLARK               4
BLAKE               4
JONES               4

ENAME           GRADE
---------- ----------
SCOTT               4
FORD                4
KING                5

14 rows selected.

可以看到 grade 有很多的重复值。

时间: 2024-11-05 17:34:12

【SQL】表连接 --半连接的相关文章

SQL表连接

  背景 在上次的自考科目<数据库系统原理>中,已经接触到了关于数据库表连接的一些知识,最近的学习过程中又用到了关于数据库表的连接问题,趁此再跟大家一起回顾一下. 导图总结 首先用一张思维导图概括一下SQL表连接的内容: 对SQL表连接有个大概的了解之后,我们通过一个小例子进一步来学习一下.首先,我建立和两张表:如下 外连接 外连接包括左外连接.右外连接和完整外连接. 左外连接 SQL语句:select * from table1 left join table2 on table1.id=t

sql 表连接数据去重-sql 表连接后数据去除重复的内容

问题描述 sql 表连接后数据去除重复的内容 有个A表 订单号 入住人 1 张1 1 王1 2 张2 3 张3 有个B表 订单号 入住房间号 1 201 1 202 两个表的订单号是相同的 现在想得到表 订单号 入住人 房间号 1 张1 201 1 王1 202 2 张2 null 3 张3 null 请问改如何写 解决方案 关键问题是你的订单号比如1,入住了两个人,分别开了两个房间,但问题是哪个人是201房间,哪个人是202房间没有对应.这个人和房间的对应关系是怎样的? 解决方案二: 这是同一

sql表连接查询使用方法(sql多表连接查询)_MsSql

实际的项目,存在多张表的关联关系.不可能在一张表里面就能检索出所有数据.如果没有表连接的话,那么我们就需要非常多的操作.比如需要从A表找出限制性的条件来从B表中检索数据.不但需要分多表来操作,而且效率也不高.比如书中的例子: 复制代码 代码如下: SELECT FIdFROM T_CustomerWHERE FName='MIKE' 这个SQL语句返回2,也就是姓名为MIKE 的客户的FId值为2,这样就可以到T_Order中检索FCustomerId等于2 的记录: 复制代码 代码如下: SE

sql表连接查询使用方法(sql多表连接查询)

实际的项目,存在多张表的关联关系.不可能在一张表里面就能检索出所有数据.如果没有表连接的话,那么我们就需要非常多的操作.比如需要从A表找出限制性的条件来从B表中检索数据.不但需要分多表来操作,而且效率也不高.比如书中的例子:复制代码 代码如下:SELECT FIdFROM T_CustomerWHERE FName='MIKE' 这个SQL语句返回2,也就是姓名为MIKE 的客户的FId值为2,这样就可以到T_Order中检索FCustomerId等于2 的记录: 复制代码 代码如下:SELEC

从两种SQL表连接写法来了解过去

例如:一个二表连接的SQL,有两种写法: (1)select A.c1,A.c2,B.c1,B.c2 from table1 A,table2 B where A.id=B.id (2)select A.c1,A.c2,B.c1,B.c2 from table1 A join table2 B on A.id=B.id 哪种写法好呢?现在提倡用哪一种? 你喜欢用哪一种? 复制代码 代码如下: select * from a,b where a.id=b.id select * from a in

sql表连接问题

问题描述 本来是selecta.zlzh,b.state,b.item1fromtabaleftjointab2bona.zlzh=b.zlzh,现在b中变成这样了,多个值在字段值中,用逗号隔开,这个能改吗???这么改 解决方案 解决方案二:这个好像改不了吧,逗号的作用就是区别出来每个字段,你这是好几个字段的值连接查询放到一个字段了吧.如果你想没有逗号的话,就写连接字符串吧,连接查询实现不了解决方案三:selecta.zlzh,b.state,b.item1fromtabaleftjointab

sql 表连接问题

问题描述 一张航空表a,字段:航班id,起始城市id,目的城市id.一张城市表b,字段:城市id,城市名称.怎样查出从北京到上海的航班id? 问题补充:yangshancheng 写道 解决方案 select a.id from a inner join b as startcity on a.start_cityid=startcity.id inner join b as endcity on a.end_cityid=endcity.id where startcity.name='北京'

sql 表连接

 join (inner join ) 注释:INNER JOIN 关键字在表中存在至少一个匹配时返回行.   left join  注释:LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配.如果右表中没有匹配,则结果为 NULL.   right join 注释:RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配.如果左表中没有匹配,则结果为 NULL.  

【SQL】表连接七种方式

---交叉连接,即是笛卡儿乘积 是一种将一个表的所有数据与另一个表中的所有的数据进行组合的操作.SQL> select e.ename,d.dname   2  from emp e,dept d; Execution Plan ---------------------------------------------------------- Plan hash value: 3429684969 ------------------------------------------------