9. 多表连接查询

        多表查询可理解为一个嵌套循环遍历。

多表连接查询有两种规范,较早的SQL92规范支持:

  • 等值连接:连接条件要求两列值相等
  • 非等值连接
  • 广义笛卡尔积:没有任何连接条件(n*m条记录)
  • 外连接 【MySQL 不支持 92规范的外连接】

        外连接就是在外连接符所在的表中增加一个”万能行“,这行记录的所有数据都是null,而且该行可以与另一个表中所有不满足条件的记录匹配。即可以把另一表中的所有记录选出来,不管是否满足条件。

SQL99规范:提供可读性更好的多表连接语法,及更多类型的连接查询

  • 交叉连接
  • 自然连接
  • 使用using子句的连接
  • 使用on子句的连接
  • 全外连接或左、右外连接。

        此外,还有一种自连接。如果同一表中的不同记录存在主、外键约束关联,则需使用自连接查询。自连接只是连接的一种用法,不是一种连接类型,SQL92、SQL99都可使用。自连接本质是把一个表当成两个表用。

CREATE TABLE emp_table ( #
建立自关联数据表

    id INT auto_increment PRIMARY KEY,

    uname VARCHAR(255),

    manager_id INT,

    FOREIGN KEY(manager_id) REFERENCES emp_table (id)

);

INSERT INTO emp_table

VALUES

    (NULL,'tang',NULL),
唐僧是老大

    (NULL,'sun',1),

    (NULL,'zhu',1),

    (NULL,'sha',1);

生成的表如下(取经团队):

"id" "uname" "manager_id"

"1"     "tang"     ""

"2"     "sun"     "1"

"3"     "zhu"     "1"

"4"     "sha"     "1"

        查询该表所有员工名及对应经理名,必须使用自连接查询。为一个表起两个别名,且查询中所有数据列都要加表别名前缀。

SELECT

     emp.id,

     emp.uname 员工名,

     mgr.uname 经理名

FROM

     emp_table emp,

     emp_table mgr

WHERE

     emp.manager_id = mgr.id;

上述查询可查询出所有的员工名及对应的经理名。

"id"  "员工名" "经理名"

"2"    "sun"    "tang"

"3"    "zhu"    "tang"

"4"    "sha"    "tang"

1、SQL92的连接查询

  •  多个数据表放在from之后,表间逗号隔开;
  • 连接条件放where之后,与查询条件间用and逻辑运算符连接;
  • 多个数据列具有相同列名时,需在同名列间用表(别)名前缀作为限制。

语法格式:

SELECT col1, col2...

FROM table1, table2...

[WHERE join_condition ]

例子:

#

# SQL92规范

#

# 查询学生信息及其Java成绩

SELECT s.*,java

FROM

    student s,  # 取别名

    grades g

WHERE

    #去掉where条件得到广义笛卡尔积

    #   s.id = g.id
 # 等值连接

    s.id = g.id

AND s.math > g.math
 # and连接过滤条件

#

#MySQL不支持SQL92规范的外连接,以下报错

#

SELECT  s.*, g.java

FROM

    student s, grades

WHERE  s.id = g.id (*); # 右外连接

2、SQL99的连接查询

        99和92原理基本相似,但99可读性更强:

  • 多数据表显式用xxx join连接,而不是依次排在from后,from后只需放一个数据表;
  • 提供了专门的连接条件子句,连接条件不再放在where后。
  • 以下查询结果均是符合条件的行的笛卡尔积。

例子:

# 交叉连接(crossjoin)

# 效果就是92的广义笛卡尔积,无需任何连接条件

SELECT

    s.*,java# 99多连接查询的from后只有一个表名

FROM

    student s

CROSS JOIN grades
g;

 

# 自然连接(natural join)

# 表面看起来无条件,但是有连接条件的,以两个表中【所有同名列】作为连接条件;

# 查询结果:为【所有同名列】数据相同行的笛卡尔积

# 如果两表没有同名列,则和交叉连接效果一样。

SELECT

    s.*,java

FROM

    student s

NATURAL JOIN grades
g;

 

# using子句连接

# 显式指定一列或多列的同名列作为连接条件;

# using指定的列必须是同名列,否则报错[Err]1054-Unknown column 'java' in 'from
clause'

SELECT

    s.*,java

FROM

    student s # join连接另一个表g

JOIN grades
g USING(id);

 

# on子句连接

# SQL99语法在on子句指定连接条件

# 每个on子句只指定一个连接条件。即如果需要N表连接,则需要N-1个join...on对。

# 查询出符合条件的行的笛卡尔积

# on子句条件可以是等值、非等值的,完全可以替换SQL92的(非)等值连接

SELECT

    s.*,java

FROM

    student s

JOIN grades
g # on指定连接条件

ON s.grade = g.java

JOIN emp_table e ON s.id > e.id;

# 最后结果集有2*2*4行

 

# 左、右、全外连接:left[outer]join、right[outer]join、full[outer]join

# outer(外),默认省略;

# on子句指定连接条件,(非)等值连接条件;

# 99外连接与92恰好相反;

# 左外连接:查询符合条件的结果集+left左边表中不符合条件的记录。

# 右外连接与左外相反;

# 全外连接:额外输出两表中所有不满足条件的记录。

SELECT

    s.*,java

FROM

    student s # RIGHT JOIN grades
g # 右外连接

LEFT JOIN grades
g # 左外连接

ON s.grade = g.java;

 

# 截止5.7.10MySQl不支持全外连接full,但可通过左外、右外连接实现

SELECT s.*,java

FROM  student
s

LEFT JOIN grades
g # 左外连接

ON s.grade = g.java

UNION(

        SELECT s.*,java

        FROM student
s

        RIGHT JOIN grades
g # 右外连接

        ON s.grade = g.java

    );

时间: 2024-12-23 22:35:54

9. 多表连接查询的相关文章

android使用ormLite,多表连接查询

问题描述 android使用ormLite,多表连接查询 解决方案

javaee-java菜鸟请问下,两个数据表连接查询问题

问题描述 java菜鸟请问下,两个数据表连接查询问题 hql="select t.id,t.name,p.lname,t.beizhu,t.human,t.city,t.lrr,t.lrtime,t.modtime,t.address from CrmCustomer t, CrmCustomerLxr p where t.tend='已成单' and p.lname like '%" + lname + "%' and t.id=p.customerid "; S

代码-linq多表连接查询速度很慢,但我在数据库查询分析器中却是秒查,请各位大侠帮我分析下

问题描述 linq多表连接查询速度很慢,但我在数据库查询分析器中却是秒查,请各位大侠帮我分析下 with temp as ( select (case when SHIFTSCHEDULEID is null then (case when TICKET_SELL_TYPE=2 then (select COMPANY_ID from TBL_YD_SHIFT where SHIFTNUMBER= (select SHIFTNUMBER from TBL_SP_TICKET where tick

oracle两表连接查询问题

问题描述 oracle两表连接查询问题 有两张表,一张是个人信息表包括考生姓名,年龄,性别等一系列个人信息和一些其他信息: 第二张表是成绩表,其中也包括部分考生信息和分数: 现在想要在打开成绩表的时候,个人信息字段就已经对应上第一张表了,不需要自己填写, 这个应该怎么实现,代码应该怎么写? 解决方案 http://zhidao.baidu.com/link?url=Rb77btoUtGFpnDID8qotZfN3TTQcPVhzseA4ecOHNZLznZB3bx89MUzJSOR29sNpFM

MySQL中基本的多表连接查询教程_Mysql

一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如:         由于其返回的结果为被连接的两个数据表的乘积,因此当有WHERE, ON或USING条件的时候一般不建议使用,因为当数据表项目太多的时候,会非常慢.一般使用LEFT [OUTER] JOIN或者RIGHT [OUTER] JOIN  2.   内连接INNER JOIN 在MySQL中把I SELECT * FROM table1 CROSS J

多对多关系多表连接查询,同一个字段同时满足多个条件

问题描述 分类表t_keytype商品表t_product分类商品关联表t_typeproducttid(分类ID)name(分类名称)pid(商品ID)name(商品名称)idpid(商品ID)tid(分类ID)1分类11商品11112分类22商品2212321422现在要表连接查询,根据分类ID字段同时满足多个条件的商品"(分类id=1and分类id=2)"查询是同一个字段多个and,请问改怎么写,尽量不要子查询因为数据量比较大,在此谢谢各位啦! 解决方案 解决方案二:网了发图,如

Access数据库多表连接查询

第一次在Access中写多表查询,就按照MS数据库中的写法,结果报语法错,原来Access的多表连接查询是不一样的 表A.B.C,A关联B,B关联C,均用ID键关联 一般写法:select * from A inner join B on A.ID=B.ID inner join C on B.ID=C.ID 此写法在Access中报错,Access对SQL语法理解方式不一样,它将两表连接后当作一个表然后再与第三个表连接,因此要改成 select * from (A inner join B o

SQL Server 2012 多表连接查询功能实例代码

废话不多说了,直接给大家贴代码了,具体代码如下所示: -- 交叉连接产生笛卡尔值 (X*Y) SELECT * FROM Student cross Join dbo.ClassInfo --另外一种写法 SELECT * FROM Student , ClassInfo -- 内连接 (Inner 可以省略) SELECT * FROM Student JOIN dbo.ClassInfo ON dbo.Student.Class = dbo.ClassInfo.ID; -- Inner Jo

Oracle多表连接查询

多个表之间关系:一对多|(多对一)  多对多 一对一 3种 关系的完整性约束:实体完整性.参照完整性.用于定义的完整性. 必须满足实体完整性和参照完整性. 实体完整性:规定了字段|属性的约束 参照完整性:关系与关系之间的引用 某个字段的约束  外键   一.笛卡尔集  笛卡尔集会在下面条件下产生: •  省略连接条件 •  连接条件无效 •  所有表中的所有行互相连接 为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件. //查询员工及部门的详细信息  但是会产生一个笛卡尔积的效果 SQ