首页 » SEO优化 » phpupdateleftjoin技巧_SQL left join 左表合并去重技巧总结

phpupdateleftjoin技巧_SQL left join 左表合并去重技巧总结

duote123 2024-11-21 0

扫一扫用手机浏览

文章目录 [+]

zyc88.blog.csdn.net/article/details/83002882

建表:

phpupdateleftjoin技巧_SQL left join 左表合并去重技巧总结

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';

插入数据:

phpupdateleftjoin技巧_SQL left join 左表合并去重技巧总结
(图片来自网络侵删)

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表的所有记录关联一次,三种关联办法实际上便是对“笛卡尔积”的处理办法不同。

标签:

相关文章

介绍百度网盘,云端存储时代的创新先锋

随着互联网技术的飞速发展,云计算已经成为现代生活不可或缺的一部分。而在这其中,百度网盘作为国内领先的云存储服务提供商,以其卓越的性...

SEO优化 2025-01-03 阅读1 评论0

介绍监控屏蔽技术,守护个人隐私的利器

随着科技的发展,监控设备已经深入到我们生活的方方面面。在享受便利的隐私安全问题也日益凸显。如何有效屏蔽监控,保护个人隐私,成为人们...

SEO优化 2025-01-03 阅读1 评论0

介绍番号观看方法,轻松驾驭影视世界

随着互联网的普及,网络影视资源日益丰富,番号作为影视作品的标识码,已经成为广大观众了解、搜索和观看影视作品的重要途径。如何正确地使...

SEO优化 2025-01-03 阅读1 评论0

介绍盗微信号黑幕,网络安全的严峻挑战

在数字化时代,微信已成为人们生活中不可或缺的通讯工具。随着微信用户数量的激增,盗微信号的事件也日益增多。本文将深入剖析盗微信号的方...

SEO优化 2025-01-03 阅读1 评论0