深入理解SQL查询--关于重复数据
SQL比较重要的一块语法就是各种关联 inner join 和 left join 是最常用的
但是很多人工作了许久之后还是没能深入理解关联关系 导致偶尔会出现主键重复
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。1 select 债券代码,交易市场 ,count(*) -- 查重主键 2 from 3 ( 4 -- 加入需要查重的代码 5 )a 6 group by 债券代码,交易市场 7 having count(*)>1
用以上这段代码可以进行查重
我就联系实际简单说明一下
首先提出一个问题 :
Q: 如果select * from A inner join B on A.a=B.b
A表的数据条数是n
B表的数据条数是m
那么结果集的数据条数范围是多少 ?
一般来说是小于等于n
把inner join 比作是找对象 A表和B表的主键找对象 找到了对象留下 放在结果集中 没找到的走开
那结果条数应该不会大于n才对
但事实呢
结果条数可以大于n
但是 如果A表的a列 在 B表的b列找到了多个对象 结果会是怎样呢 ?
1 select * from 2 ( 3 select a=1,c=1 4 )a 5 inner join 6 ( 7 select b=1,c=2 8 union all 9 select b=1,c=3 10 )b on a.a=b.b
执行一下上面的SQL语句 结果是会返回2条数据
inner join 换成 left join 结果是一样的
理解这个对于写出不重复的SQL很重要
-------------------------
我们可以简单的这样理解 SQL关联像是找对象 , 而每个表(A和B)中的字段都是结果集的一个标签 , 也就是列 columns
你可以在最外面的select语句后面对这些标签字段进行各种处理 比如case when 然后返回新的标签列 用 as 命名
-----------------------------------补充一个难点
如果你理解了上面的结论 那么你写多表关联的话就很轻松了
但是 有一个问题
1 select symbol='001',rn=1 -- 第一个查询 2 union all 3 select symbol='001',rn=2 4 5 6 select symbol,rn1=max(case when rn=1 then rn else null end),rn2=max(case when rn=2 then rn else null end) -- 第二个查询 7 from ( 8 select symbol='001',rn=1 9 union all 10 select symbol='001',rn=2 11 )a group by symbol
如上图 第一个查询
用symbol字段关联一个表 会关联出两条数据 rn=1 和 rn=2
但是我的查询结果中不能有symbol重复 而这两条数据我都想要 该怎么处理
那就改写成第二个查询 可以做到把两条数据合并成一条 而且能取出所有想要的字段
如果不进行这样的转换 就需要多left join 一个表
这样大大简化了写法
