zyc88.blog.csdn.net/article/details/83002882
建表:
CREATETABLE`table1`(`id`int(11)NOTNULLAUTO_INCREMENT,`name`varchar(60)DEFAULTNULL,`age`varchar(200)DEFAULTNULL,`sponsor_id`varchar(20)DEFAULTNULLCOMMENT'业务发起人',`gmt_create_user`int(11)NOTNULLCOMMENT'创建人id',`gmt_create`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'创建韶光',`gmt_modified`datetimeDEFAULTNULLCOMMENT'修正韶光',`gmt_modified_user`int(11)DEFAULTNULLCOMMENT'修君子id',PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=12DEFAULTCHARSET=utf8mb4COMMENT='测试表1';CREATETABLE`table2`(`kid`int(11)NOTNULLAUTO_INCREMENT,`name`varchar(60)DEFAULTNULL,`sponsor_id`varchar(20)DEFAULTNULLCOMMENT'业务发起人',`type`int(11)NOTNULLCOMMENT'创建人id',`gmt_create`datetimeNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'创建韶光',`gmt_modified`datetimeDEFAULTNULLCOMMENT'修正韶光',`gmt_modified_user`int(11)DEFAULTNULLCOMMENT'修君子id',PRIMARYKEY(`kid`))ENGINE=InnoDBAUTO_INCREMENT=12DEFAULTCHARSET=utf8mb4COMMENT='测试表2';
插入数据:

INSERTINTO`table1`(`id`,`name`,`age`,`sponsor_id`,`gmt_create_user`,`gmt_create`,`gmt_modified`,`gmt_modified_user`)VALUES(1,'t1','11','10',1,'2018-10-1020:34:03',NULL,NULL);INSERTINTO`table1`(`id`,`name`,`age`,`sponsor_id`,`gmt_create_user`,`gmt_create`,`gmt_modified`,`gmt_modified_user`)VALUES(2,'t2','12','10',2,'2018-10-1020:34:03',NULL,NULL);INSERTINTO`table1`(`id`,`name`,`age`,`sponsor_id`,`gmt_create_user`,`gmt_create`,`gmt_modified`,`gmt_modified_user`)VALUES(3,'t3','13','10',3,'2018-10-1020:34:03',NULL,NULL);INSERTINTO`table1`(`id`,`name`,`age`,`sponsor_id`,`gmt_create_user`,`gmt_create`,`gmt_modified`,`gmt_modified_user`)VALUES(4,'t4','14','20',4,'2018-10-1020:34:03',NULL,NULL);
INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (1, 't1', '10', 1, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (2, 't2', '10', 1, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (3, 't3', '10', 1, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (4, 't4', '10', 1, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (5, 't5', '10', 1, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (6, 't6', '10', 1, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (7, 't7', '10', 2, '2018-10-10 20:38:10', NULL, NULL);INSERT INTO `table2`(`kid`, `name`, `sponsor_id`, `type`, `gmt_create`, `gmt_modified`, `gmt_modified_user`) VALUES (8, 't1', '11', 1, '2018-10-10 20:38:10', NULL, NULL);
查询非常:
SELECTa.,b.typeFROMtable1aLEFTJOINtable2bONa.sponsor_id=b.sponsor_idWHEREb.type=1ANDa.sponsor_id=10;
MySQL left join 语句格式为:A LEFT JOIN B ON 条件表达式
left join 因此A表为根本,A表即左表,B表即右表。
左表(A)的记录会全部显示,而右表(B)只会显示符合条件表达式的记录,如果在右表(B)中没有符合条件的记录,则记录不敷的地方为NULL。
利用left join, A表与B表所显示的记录数为 1:1 或 1:0,A表的所有记录都会显示,B表只显示符合条件的记录。
但如果B表符合条件的记录数大于1条,就会涌现1:n的情形,这样left join后的结果,记录数会多于A表的记录数。
以是办理办法 都是从一个出发点出发,使A表与B表所显示的记录数为 1:1对应关系。
办理方法:利用非唯一标识的字段做关联
1 DISTINCT
select DISTINCT(id) from a left join b on a.id=b.aid DISTINCT查询结果是 第一个表唯一的数据 重复的结果没显示出来
SELECTDISTINCT(a.id),a.,b.typeFROMtable1aLEFTJOINtable2bONa.sponsor_id=b.sponsor_idWHEREb.type=1ANDa.sponsor_id=10;
SELECTDISTINCTa.,b.typeFROMtable1aLEFTJOINtable2bONa.sponsor_id=b.sponsor_idWHEREb.type=1ANDa.sponsor_id=10;
2 GROUP BY
select from a left join(select id from b group by id) as b on a.id=b.aid拿出b表的一条数据关联 使A表与B表所显示的记录数为 1:1对应关系。
SELECTa.,b.typeFROMtable1aLEFTJOIN(SELECTFROMtable2GROUPBYsponsor_id)ASbONa.sponsor_id=b.sponsor_idWHEREb.type=1ANDa.sponsor_id=10;
3 max取唯一
select from a left join (select max(id) from table group by id) as b on a.id=b.aid 拿出b表的末了一条数据关联
SELECTa.,b.typeFROMtable1aLEFTJOIN(SELECTMAX(kid),type,sponsor_idFROMtable2GROUPBYsponsor_id)ASbONa.sponsor_id=b.sponsor_idWHEREb.type=1ANDa.sponsor_id=10;
4 IN巧用
SELECTa.FROMtable1aWHEREa.sponsor_idIN(SELECTsponsor_idFROMtable2WHEREtype=1ANDsponsor_id=10);
SELECTa.,1FROMtable1aWHEREa.sponsor_idIN(SELECTsponsor_idFROMtable2WHEREtype=1ANDsponsor_id=10);
相信对付熟习SQL的人来说,LEFT JOIN非常大略,采取的时候大概多,但是有个问题还是须要把稳一下。如果一个主表M有多个从表的话A B C …..的话,并且每个表都有筛选条件,那么把筛选条件放到哪里,就得把稳喽。
(搜索"大众年夜众号Java知音,回答“2021”,送你一份Java口试题宝典)
比如有个主表M,卡号是主键。
有个从表A,客户号、联系办法是联合主键,个中联系办法,1-座机,2-手机号码
如果想要查询所有卡号对应的手机号码两个字段,很大略,SQL语句如下:
SELECTA.卡号,B.手机号码FROMALEFTJOINBONA.客户号=B.客户号WHEREB.联系办法='2'
相信很多人这样写,估计实际事情中也会看到这样的语句,并不是说这么写一定会缺点,实际SQL表达的思想一定是要符合业务逻辑的。
前面已经说清楚,所有卡号对应的手机号码。所有卡号,以是首先肯定以A表作为主表,并且左关联B表,这样A表所有的卡号一定会显示出来,但是如果B表的筛选条件放到最外层,这样就相称于将A表关联B表又做了一遍筛选,结果便是
就会筛选出来这么一条数据,丢失了A表中其他的卡号。
实际事情中表构造肯定没这么大略,关联的表也会很多,当有很多条件时,最好这么写
SELECTA.卡号,B.手机号码FROMALEFTJOIN(SELECTFROMBB.联系办法='2')BONA.客户号=B.客户号
这么写的话,A表中的数据肯定会完备保留,又能与B表的匹配,不会丢失数据。
PS:
表构造Left JoinRight JoinInner Join表的关联修正和删除笛卡尔积1、表构造
左A右B
2、Left Join
示例:2.1
SelectFromAleftjoinBonA.aid=B.bid;
left join因此A表的记录为根本的,A可以算作左表,B可以算作右表,left join因此左表为准的。换句话说,左表A的记录将会全部表示出来,而右表B只会显示符合搜索条件的记录(例子中为: A.aid = B.bid),B表记录不敷的地方均为NULL.
A表所有记录都会显示,A表中没有被匹配的行(如aid=5、6的行)相应内容则为NULL。返回的记录数一定大于A表的记录数,如A表中aid=7行被B表匹配了3次(由于B表有三行bid=7)。把稳:在Access中A.aid、B.bid不能缩写成aid、bid,否则会提示“不支持链接表达式”,这一点不同于Where查询。
3、Right Join
示例:3.1
SelectFromArightjoinBonA.aid=B.bid;
仔细不雅观察一下,就会创造,和left join的结果刚好相反,这次因此右表(B)为根本的,A表不敷的地方用NULL添补。
4、Inner Join
示例:4.1
SelectFromAinnerjoinBonA.aid=B.bid;
这里只显示出了 A.aid = B.bid的记录.这解释inner join并不以谁为根本,它只显示符合条件的记录。
inner join 等同于Where查询如:
SelectFromA,BWhereA.aid=B.bid
5、表的关联修正和删除
5.1修正
示例:5.1.1
updateAleftjoinBonA.aid=B.bidsetA.aname=B.bname
上述SQL实际操作的表为"Select From A left join B on A.aid = B.bid",因此Access会提示更新13条记录(Select查询出的记录便是13条)。比拟“示例:2.1”返回的结果,剖析update后的A表:
aid=5、6的记录,被更新为NULLaid=7的记录,被更新了3次,依次是“b1997-1”、“b1997-2”、“b1997-3”,因此其结果为末了一次更新“b1997-3”对付上述SQL同样可以将“A.aname = B.bname”改成“B.bname = A.aname”,实行后B表将会被修正,但是实行后B表会增加三行“0, a2005-1;0, a2005-2;0, a2006”,这也不难明得,由于Left Join实行后,B表会涌现三行空值。
示例:5.1.2
Where条件查询在上面的SQL中同样可以利用,其浸染的表也是Select查询出的关联表。如下SQL
updateAleftjoinBonA.aid=B.bidsetA.aname=B.bnamewhereA.aid<>5
实行后A表的结果:
比拟第一次update可以创造,aid=5的并没有被更新。
这里只讲述left join,由于right join 和 inner join的处理过程等同于left join。其余Access中update语句中不能含有From关键字,这一点不同于其他数据库。
5.2删除
在Access中是否可以通过Left Join、Right Join、Inner Join来删除某张表的记录
示例:5.2.2
DeleteFromAinnerjoinBonA.aid=B.bidwhereB.bname="b1991"
上述SQL的本意是删除A表中aid=1的记录,但实行后表A和表B均未发生任何变革。若想实现此目的,下述SQL可以实现
DeleteFromAWhereA.aidIn(SelectbidFromBWhereB.bname="b1991")
6、笛卡尔积
如果A表有20条记录,B表有30条记录,则二者关联后的笛卡尔积工2030=600条记实录。也便是说A表中的每条记录都会与B表的所有记录关联一次,三种关联办法实际上便是对“笛卡尔积”的处理办法不同。