SQL 连接查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 连接查询相关的知识,希望对你有一定的参考价值。

假设有2张表:tb_house, tb_custm。tb_custm中存有客户,包括房东和房客。我想在查询一个house的同时把该house的房东和房客都查询出来,请问连接查询的语句如何写?
房东和房客在tb_custm中是用同一个字段表示的。用ID和tb_house连接。

不懂就看看
SQL-92标准所定义的FROM子句的连接语法格式为:

FROM join_table join_type join_table

[ON (join_condition)]

其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一个表操作的连接又称做自连接。

join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。

外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。

交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。

无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info

FROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接

内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分三种:

1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:

SELECT *

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):

SELECT a.*,p.pub_id,p.pub_name,p.country

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

(二)外连接

内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。

如下面使用左外连接将论坛内容和作者信息连接起来:

SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b

ON a.username=b.username

下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:

SELECT a.*,b.*

FROM city as a FULL OUTER JOIN user as b

ON a.username=b.username

(三)交叉连接

交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等

于6*8=48行。

SELECT type,pub_name

FROM titles CROSS JOIN publishers

ORDER BY type
参考技术A 你说的这个数据库是你自己设计的?怎么可以把房东和房客用一个字段表示呢?
想不通这么设计有什么好!很麻烦啊!
像你所说的情况是可以通过INNER JOIN来做,但是在区分房东房客的时候你怎么做?你如何显示出来谁是房东谁是房客?有第三张表?
如果是我的话我会把房东放进第三张表为td_house_owner_info(td_house_owner_id,名字电话那一系列信息字段)然后td_custom里会有房客_ID,td_house_id(房东房客可以是多对多的关系,但是一个房子的话只能对应一个房客(插间除外))租住开始时间,租住几个月?租金?以及一些信息!·这样你在这里只需要在td_house中设计td_house_id,td_house_owner_ID,这样细分下来你就可以实现更多更细更强的功能了!看你写SQL语句的能力了!我懒的写,只喜欢做些SS的设计!实不实用可以一步一步改么!
参考技术B 1:以我的理解,你的表是这样的
tb_house
id adrress custm_id

tb_ custm
custm_id name custm_type phonenum
要查找的结果是
id 房东 房客

declare @sql varchar(1000)
set @sql='select id'
select @sql=@sql+',max(case custm_type when '''+custm_type+''' then custm_id else 0 end)['+custm_type+']'
from (select distinct custm_type from (select b.id id,a.name name,a.type type from tb_custm a,tb_house b where a.custm_id=b.custm_id and b_id='这里填要查找的房子编号' )as b)as a
set @sql=@sql+'from (select b.id id,a.name name,a.type type from tb_custm a,tb_house b where a.custm_id=b.custm_id and b_id='这里填要查找的房子编号' )as b group by id'
exec(@sql)
参考技术C 如果用Id的语

就用这个语句

select b.* from tb_custm a,tb_house b where a.id=b.id and b.id='房屋编号'

假如
tb-house与tb_custm的

关联关键字是houseId

我们要查询的房屋编号是"001"

select b.* from tb_custm a,tb_house b where a.houseid=b.houseid and b.houseid='001'
参考技术D select tb_house.*,tb_custm.* from tb_house,tb_custm where (tb_house.房号=N) AND tb_house.房号=tb_custm.房号

sql面试题_sql_分组查询左连接和右连接的区别

面试常考分组查询题目汇总

分组查询题目一

有如下表结构,数据如下
.表test结构:

    grop       score
    a           胜
   b         负
   a         负
    b           胜

请写出sql语句,使检索结果如下

  组    胜  负
  a     1     1
    b     1    1

这很明显是一一道分组查询的题目,那么应该如何解答呢

分析
完整数据如下
在这里插入图片描述

  SELECT grop as '组' ,
			 count(case when score='胜' then score end) as '胜',
			 count(case when score='负' then score else null end) as '负'
			 from test1 GROUP BY grop

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SELECT grop '组',
			 count(case when score='胜' then score end) '胜' ,
			 count(case when score='负' then score end) '负' 
FROM test1 group by grop

能写到这步就可以了

分组查询题目二

表a结构

  aid  aname

   1    a

   2    b

表b结构

  bid  aid  bname

   1   1    111111

   2    2    222222

   3    1    333333

要求
检索结果

  aid  aname   bcount

   1     a      2

   2    b     1

分析,如果是左连接,那么就会是这样,我们的表b的 bid为3的数据直接就丢失了

连接查询:内连接、外连接(左连接、右连接)

在这里插入图片描述
如果是右连接呢
在这里插入图片描述

联合查询

什么叫联合查询,这里我们注意看联合查询和连接查询的区别
联合查询结果是将多个select语句的查询结果合并到一块因为在某种情况下需要将几个select语句查询的结果合并起来显示。
比如需要查询两个公司的所有员工的信息,这就需要从甲公司查询所有员工信息,再从乙公司查询所有的员工信息,然后将两次的查询结果进行合并。
可以使用union和union all关键字进行操作
注意
其中union选项有两个选项可选
all:表示无论重复都输出
distinct: 去重(整个重复)(默认的)
在这里插入图片描述
== 特别注意联合查询需要两张表的表结构是一样的,否则会报错==

我们继续看题

要求根据a表和b表
检索出结果

  aid  aname   bcount

   1     a      2

   2    b    1

这sql语句要怎么写呢
 在这里插入图片描述
在这里插入图片描述
好家伙,感觉还是不对
完了,这下好了,不会了
检查后发现,是我数据库里面 b表数据不对,其实我查出来是正确的
在这里插入图片描述
在这里插入图片描述
再查询一下,就对了
在这里插入图片描述

select aid,
		   aname,
		  (select count(*) from b where a.aid=b.aid) as bcount
			from a
			

以上是关于SQL 连接查询的主要内容,如果未能解决你的问题,请参考以下文章

sql子查询和连接查询的区别是啥呢?

sql多表连接查询问题

SQL怎么连接查询2个表?

SQL怎么连接查询2个表?

一文让你彻底理解SQL连接查询

连接两表查询结果的SQL语句