Sql 如果超过1个值符合条件,则将值合并到单个列中

Sql 如果超过1个值符合条件,则将值合并到单个列中,sql,sql-server,Sql,Sql Server,我正在尝试编写一个查询来返回用户、关于他们的一些信息以及他们被分配到哪个安全组。但是,有些用户有多个组,因此我不返回两行,而是合并安全组名称 SELECT ur.loginname ,ur.firstname ,ur.lastname ,sg.securitygroupname ,jt.description FROM users ur ,usersecuritygroup us ,secu

我正在尝试编写一个查询来返回用户、关于他们的一些信息以及他们被分配到哪个安全组。但是,有些用户有多个组,因此我不返回两行,而是合并安全组名称

SELECT  ur.loginname 
       ,ur.firstname 
       ,ur.lastname 
       ,sg.securitygroupname 
       ,jt.description 
FROM    users ur 
       ,usersecuritygroup us 
       ,securitygroup sg
       ,jobtitle jt 
WHERE  ur.doctorfacilityid = us.doctorfacilityid 
       AND us.securitygroupid = sg.securitygroupid 
       AND ur.jobtitle = jt.jtid 
因此,不要像这样得到两行:

jdoe     john     doe     group1     xyz
jdoe     john     doe     group2     xyz
jdoe     john     doe     group1, group2   xyz
我想像这样返回1行:

jdoe     john     doe     group1     xyz
jdoe     john     doe     group2     xyz
jdoe     john     doe     group1, group2   xyz

安全组将是唯一一个有多行符合条件的列(如果这很重要)。

您可以将查询放入CTE并使用XML连接
securitygroupname
列中的值,或者如果您使用的是SQL Server 2017,则可以使用
STRING\u AGG()
函数

with cte as (
    SELECT  ur.loginname 
           ,ur.firstname 
           ,ur.lastname 
           ,sg.securitygroupname 
           ,jt.description 
    FROM    users ur 
           ,usersecuritygroup us 
           ,securitygroup sg
           ,jobtitle jt 
    WHERE  ur.doctorfacilityid = us.doctorfacilityid 
           AND us.securitygroupid = sg.securitygroupid 
           AND ur.jobtitle = jt.jtid
)
-- OLD VERSIONS
select distinct
    loginname
    ,firstname
    ,lastname
    ,STUFF(
        (SELECT
            N', ' + securitygroupname
        FROM cte c
        WHERE loginname = c.loginname
            and firstname = c.firstname
            and lastname = c.lastname
            and description = c.description
        FOR XML PATH(''), type).value('text()[1]', 'nvarchar(max)'), 1, 2, N''
    ) securitygroupname
    ,description
from cte

-- STARTING SQL SERVER 2017
select
    loginname
    ,firstname
    ,lastname
    ,STRING_AGG(securitygroupname, ',') as securitygroupname
    ,description
from cte
group by loginname, firstname, lastname, description

大家好,欢迎来到SO。既然您说您是sql新手,我强烈建议您开始使用ANSI-92样式的联接。他们现在已经有超过25年的历史了。对于手头的问题,它已经被问了几百次,回答了几百次。我最喜欢的一篇关于这个话题的文章可以在里面找到,里面的,外面的,左边的,右边的等等,让我很困惑。很抱歉,我是一名业务系统分析师,所以我确信我的SQL需求不会超出这个范围。至于搜索,我尝试过搜索。我更愿意找到答案,然后等待别人给我答案。看起来我缺少的关键字是“concatenate”。作为一个新手,我查看了您提供的链接,我甚至不知道如何使用它来更改我自己的查询,因为它远远超出了我的理解范围。我没有意识到这个解决方案会如此复杂(至少对我来说是如此),您要做的是将多行数据强制放到一列中。这不是关系数据的工作方式,因此解决方案并不简单。如果您使用的是SQL Server 2017+您可以使用。谢谢,伙计,我在编辑答案时,您评论道:)谢谢!我会看看是否能解决这个问题。我们有SQL server 2017,但出现错误,“STRING_AGG”不是可识别的内置函数名。@Valerica我必须使用旧版本,但它显示的是用户不属于的安全组以及重复组。例如,我是2个组的一部分,该查询为我返回了114个组。其中33个是一组的重复,5个是我所在的另一组的重复。其他78个是(30个独特的群体)我不在其中。