SQL技术问询:同表同列值合并一行及双表关联查询
嘿,我来帮你搞定这两个SQL问题,咱们一个个来:
需求1:从同一数据库表的同一列中获取数据并合并到同一行
不同数据库的实现函数略有差异,我给你列几个常用场景的写法:
- SQL Server、PostgreSQL、Azure SQL:用
STRING_AGG函数SELECT 分组字段名, -- 比如UserID,按这个字段分组合并 STRING_AGG(要合并的列名, ', ') AS 合并后列名 FROM 你的表名 GROUP BY 分组字段名; - MySQL、MariaDB:用
GROUP_CONCAT函数SELECT 分组字段名, GROUP_CONCAT(要合并的列名 SEPARATOR ', ') AS 合并后列名 FROM 你的表名 GROUP BY 分组字段名; - Oracle:用
LISTAGG函数SELECT 分组字段名, LISTAGG(要合并的列名, ', ') WITHIN GROUP (ORDER BY 要合并的列名) AS 合并后列名 FROM 你的表名 GROUP BY 分组字段名;
简单说下逻辑:先通过GROUP BY按你需要的维度(比如用户ID)分组,再用对应数据库的字符串聚合函数,把同一组里的列值拼接成一行,分隔符可以自己调整(比如换成;或者空格)。
需求2:关联X_User_Role和Role表的SELECT语句
根据你的表结构和数据,我推测你想要的是每个用户的主角色、次角色分别显示在不同列的结果,这里给你两种靠谱的实现方式:
方法1:条件聚合(推荐,灵活度高)
SELECT ur.UserID, MAX(CASE WHEN r.SecondaryFl = 0 THEN r.Name END) AS PrimaryRole, MAX(CASE WHEN r.SecondaryFl = 1 THEN r.Name END) AS SecondaryRole FROM X_User_Role ur JOIN Role r ON ur.RoleID = r.RoleID GROUP BY ur.UserID;
逻辑很清晰:先把两张表关联起来,用CASE语句分别筛选主角色(SecondaryFl=0)和次角色(SecondaryFl=1),再用MAX聚合(因为每个用户对应每种类型的角色最多一个,用MIN也可以),最终把同一用户的两个角色分到不同列。
方法2:两次JOIN(适合新手理解)
SELECT ur1.UserID, r1.Name AS PrimaryRole, r2.Name AS SecondaryRole FROM X_User_Role ur1 JOIN Role r1 ON ur1.RoleID = r1.RoleID AND r1.SecondaryFl = 0 LEFT JOIN X_User_Role ur2 ON ur1.UserID = ur2.UserID LEFT JOIN Role r2 ON ur2.RoleID = r2.RoleID AND r2.SecondaryFl = 1 GROUP BY ur1.UserID, r1.Name, r2.Name;
这里先通过JOIN拿到用户的主角色,再用LEFT JOIN关联次角色(这样没有次角色的用户也会保留,不会被过滤掉,对应列显示NULL)。
执行后会得到符合预期的结果:
| UserID | PrimaryRole | SecondaryRole |
|---|---|---|
| 1 | PrimaryRole | SecondaryRole |
| 2 | PrimaryRole | NULL |
内容的提问来源于stack exchange,提问作者nitinvertigo
相关产品推荐
相关产品推荐

