基础SQL演练,带详细分析,笔记和备忘。
目录
背景介绍
表数据
需求1:查询g表所有记录,以及关联的h的id
需求2:在需求1基础上,查出关联的h的其它字段(name)
需求3:在需求2基础上,按gid分组、同时把对应的多个h表的字段各自放在一起
方式1
方式2
背景介绍
共三个表,g和h表分别是各自数据、无关联关系。另有k表维护了g和h表的关联关系,内容是k中包含了g_id和h_id两个字段,这两个字段分别和g表的id、h表的id相等,且各自一一对应。
表数据
g表
h表
m表
需求1:查询g表所有记录,以及关联的h的id
select g.id gid,g.name gname,m.h_id hid
from demo_gs g
left join demo_ms m
on m.g_id = g.id
结果
没什么问题。
需求2:在需求1基础上,查出关联的h的其它字段(name)
select g.id gid,g.name gname,m.h_id hid,h.name as hname
from demo_gs g
left join demo_ms m
on m.g_id = g.id
left join demo_hs h
on h.id = m.h_id
结果:
可以看到结果正确。
需求3:在需求2基础上,按gid分组、同时把对应的多个h表的字段各自放在一起
方式1
我们将对应多个的数据使用字符串拼接的方式拼一起,以逗号分隔
pg中可以使用STRING_AGG( CONCAT(h.id, ': ', h.name),'; ')
select g.id gid,g.name gname,group_concat(h.id SEPARATOR ',') hids ,group_concat(h.name SEPARATOR ',') hnames
from demo_gs g
left join demo_ms m
on m.g_id = g.id
left join demo_hs h
on h.id = m.h_id
group by gid
结果如下:
方式2
把对应多个的数据的地方使用json构建(适配支持JSON功能的数据库,JSON_OBJECTAGG在pg中不适用):
select g.id gid,g.name gname,JSON_OBJECTAGG(h.id,JSON_OBJECT('hname', h.name)) as hData
from demo_gs g
inner join demo_ms m
on m.g_id = g.id
left join demo_hs h
on h.id = m.h_id
group by gid
结果如下:
注意,之所以方式2 inner join demo_ms m 这里使用了内连,原因是mysql中做JSON处理时要求数据不能为空:[22001]: Data truncation: JSON documents may not contain NULL member names.
因为这时g表和h表各有一条id=6的数据在m中没有做关联,在做JSON_OBJECTAGG操作时就会报上述错误。因此只能采用内连,屏蔽掉为空的记录。