You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL关联多表聚合地址字符串的SQL查询问题

获取学生在校及大学阶段去过的地点(PostgreSQL)

表结构与需求

现有数据库表及数据如下:

Student表

IdName
1Roger
2Roman

School表

IdNameAddress_IdStudent_Id
1School111
2School221
3School332

College表

IdNameAddress_IdStudent_Id
1College111
2College232

Address表

IdName
1Brooklyn
2Manhattan
3Troy

需要查询出学生ID、姓名,以及他们在学校和大学阶段去过的所有地点(去重后用逗号分隔),期望结果:

IDStudent NameVisited Places
1RogerBrooklyn, Manhattan
2RomanTroy

原SQL无法运行:

SELECT 
   s.Id AS 'ID', 
   s.Name AS 'Student Name',
   STRING_AGG(a.Name, ', ')AS 'Visited Places'
FROM Student s
   LEFT JOIN School sc ON sc.Student_Id = s.Id
   LEFT JOIN Address a ON a.Id = sc.Address_Id
   LEFT JOIN College c ON c.Student_Id = s.Id
   LEFT JOIN Address a ON a.Id = c.Address_Id;

问题分析

  • 重复使用了别名a关联Address表,PostgreSQL不允许同一查询中重复定义相同别名
  • 未对重复地点去重,比如Roger的Brooklyn在学校和大学都存在,会被重复统计
  • 缺少GROUP BY子句,使用聚合函数STRING_AGG时必须按非聚合字段分组

正确查询语句

SELECT
    s.Id AS "ID",
    s.Name AS "Student Name",
    STRING_AGG(DISTINCT a.Name, ', ') AS "Visited Places"
FROM Student s
LEFT JOIN (
    -- 合并学校和大学的学生-地址关联记录,自动去重重复条目
    SELECT Student_Id, Address_Id FROM School
    UNION
    SELECT Student_Id, Address_Id FROM College
) AS sc_c ON sc_c.Student_Id = s.Id
LEFT JOIN Address a ON a.Id = sc_c.Address_Id
GROUP BY s.Id, s.Name;

说明

  1. 用UNION合并School和College表的学生地址关联数据,UNION会自动去除重复的(Student_Id, Address_Id)组合
  2. 使用DISTINCT确保聚合时每个地点只出现一次,避免同一地点多次显示
  3. 添加GROUP BY s.Id, s.Name满足聚合函数的分组要求,确保每个学生对应一条结果

内容的提问来源于stack exchange,提问作者Ricky Vikram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:17:38