我正在使用SQL工作台。这是我有的表格的一个例子:
SITES
id
BUILDINGS
id
site_id
LEVELS
id
building_id
我还没有创建这个数据库,也无法修改它。每个建筑都对应一个网站,所以它包含一个指向该网站的KEY。与标高和建筑物相同。
我正在尝试得到这个结果
site_id | buildings_id | levels_id
1 | 15, 16 | (213, 214), (313, 314)
2 | 21, 22, 23 | (350), (400, 401, 402), (501)
3 | 31, 32, 33, 34 | (5001, 5002), (7001), (8009), (8400)
前两列很容易,但我对第三列有问题。括号是说明性的,我不一定需要。但我需要一种通过building_id将字符串拆分为级别的方法。
每个(…(对应于一栋建筑中的标高。
这是我现在处理的查询,它返回第一列和第二列。我尝试向查询添加另一个LEFT OUTER JOIN,但没有成功。我尝试了很多事情,但我尝试的大多数事情都会返回错误或奇怪的输出。
SELECT
sites.id AS site_id,
GROUP_CONCAT(DISTINCT buildings.id
SEPARATOR '; ') AS buildings_id
FROM
sites
LEFT OUTER JOIN
users_has_sites ON users_has_sites.sites_id = sites.id
LEFT OUTER JOIN
users ON users.id = users_has_sites.users_id
LEFT OUTER JOIN
buildings ON buildings.sites_id = sites.id
WHERE
users.id = 42
GROUP BY site_id;
感谢您的帮助。感谢
您需要两个级别的聚合:一个由building_id
聚合,另一个由site_id
聚合。
with b_l as ( select b.id as building_id , b.site_id , concat('(' , group_concat( l.id order by l.id separator ',' ) , ')' ) as building_levels from buildings as b left join levels as l on b.id = l.building_id group by b.id, b.site_id ) , s_b as ( select s.id , group_concat( b_l.building_id order by b_l.building_id separator ',' ) as buildings , group_concat( b_l.building_levels order by b_l.building_id separator ',' ) as levels from sites as s left join b_l on s.id = b_l.site_id group by s.id ) select * from s_b
id|buildings|levels-:|:--------|:----------------------1|1,2,3|(1,2(,(3,4,5(2|4,5,6|(7,8(,(9(,(10,11(3|7,8,9|(12,13,14(,(15,16(,(17(4|10|null
或与横向连接相同:
select s.id , group_concat( b_l.building_id order by b_l.building_id separator ',' ) as buildings , group_concat( b_l.building_levels order by b_l.building_id separator ',' ) as levels from sites as s left join lateral ( select b.site_id , b.id as building_id , concat('(' , group_concat( l.id order by l.id separator ',' ) , ')' ) as building_levels from buildings as b left join levels as l on b.id = l.building_id group by b.id, b.site_id ) b_l on s.id = b_l.site_id group by s.id
db<gt;小提琴这里
根据您的需求和表结构推断你可以试试这个sql
选择site.id、GROUP_CONNCT(c.building_id(building_id、GROUP-CONNCT(c.level_id(levels_id从现场(选择building.site_id,building.id building_id,concat('(',GROUP_CONCT(level
.id(,'('(level_id从建筑,level
WHERE building.id=level
.building_id GROUP BY building.id)c,其中site.id=c.site_id按站点分组.id;
您可以使用两个级别的聚合,从最低级别开始:
SELECT site_id,
GROUP_CONCAT(building_id ORDER BY building_id SEPARATOR ', ') as building_ids,
GROUP_CONCAT('(', levels, ')' ORDER BY building_id SEPARATOR ', ') as levels
FROM (SELECT s.id AS site_id, b.id as building_id,
GROUP_CONCAT(l.id ORDER BY l.id SEPARATOR ', ') as levels
FROM sites s LEFT JOIN
users_has_sites uhs
ON uhs.sites_id = s.id LEFT JOIN
buildings b
ON b.sites_id = s.id LEFT JOIN
levels l
ON l.building_id = b.id
WHERE uhs.users_id = 42
GROUP BY site_id, b.id
) sb
GROUP BY site_id;
请注意,不需要users
表,因为id在junction表中。此外,可能不需要sites
,但您正在将其用于LEFT JOIN
(尽管WHERE
子句将其转换为INNER JOIN
(。不过我把它忘了。