簡體   English   中英

連接sql server中的值並按另一個值分組 ms sql服務器

[英]Concatenate values in sql server and group by another value | ms sql server

我有簡單的選擇

select distinct  UserName, Company from Users inner join Companies on Users.UserName = Companies.UserFullName

查詢結果如下:

  User1 | Company1
  User1 | Company2
  User1 | Company3
  User1 | Company4
  User2 | Company3
  User2 | Company6
  User2 | Company1
  User2 | Company5

我想連接公司值並按用戶分組。 像這樣:

  User1 | Company1 , Company2 , Company3 , Company4
  User2 | Company3 , Company6 , Company1 , Company5

是否有可能在sql server中做?

如果您使用的是SQL Server 2017,則可以使用新功能STRING_AGG

SELECT UserName,
       STRING_AGG(Company,' , ') WITHIN GROUP (ORDER BY Company) AS Companies
FROM #T1
GROUP BY Username;

請注意,您的表中沒有排序,因此,除非您有其他要排序的列,否則不能為'User2'保留'Company3, Company6, Company1, Company5'順序。

以下代碼段適用於您-

CREATE TABLE #t1 (UserName VARCHAR(100), Company VARCHAR(100));
INSERT #t1 values ('User1','Company1');
INSERT #t1 values ('User1','Company2');
INSERT #t1 values ('User1','Company3');
INSERT #t1 values ('User1','Company4');
INSERT #t1 values ('User2','Company3');
INSERT #t1 values ('User2','Company6');
INSERT #t1 values ('User2','Company1');
INSERT #t1 values ('User2','Company5');
GO
select
    UserName,
    stuff((
        select ',' + t.[Company]
        from #t1 t
        where t.UserName = #t1.UserName
        order by t.[Company]
        for xml path('')
    ),1,1,'') as CompanyName
from #t1
group by UserName;

另一個不需要FOR XML PATH子句的解決方案此解決方案基於循環

    SET NOCOUNT ON
    IF OBJECT_ID ('tempdb..#t1') IS NOT NULL DROP TABLE #T1;
    IF OBJECT_ID ('tempdb..#t2') IS NOT NULL DROP TABLE #T2;

    CREATE TABLE #t1 (UserName VARCHAR(100), Company VARCHAR(100));
    INSERT #t1 values ('User1','Company1');
    INSERT #t1 values ('User1','Company2');
    INSERT #t1 values ('User1','Company3');
    INSERT #t1 values ('User1','Company4');
    INSERT #t1 values ('User2','Company3');
    INSERT #t1 values ('User2','Company6');
    INSERT #t1 values ('User2','Company1');
    INSERT #t1 values ('User2','Company5');
    GO

    DECLARE @Table TABLE (UserName VARCHAR(100), Combined VARCHAR(4000))
    DECLARE @i INT = 1 

    SELECT DENSE_RANK () OVER (ORDER BY UserName) Seq,  *
    INTO #T2
    FROM #t1

    WHILE @i <= (SELECT MAX(Seq) FROM #T2)
        BEGIN 
        DECLARE @ConcatedCompany VARCHAR(4000) = ''
        SELECT @ConcatedCompany+= ',' + Company
        FROM #T2
        WHERE Seq = @i

        INSERT INTO @Table (UserName , Combined)
        SELECT UserName , STUFF(@ConcatedCompany,1,1,'')
        FROM #T2
        WHERE Seq = @i
        GROUP BY UserName 

        SET @i +=1

        END

    SELECT * 
    FROM @Table

UPDATE!

Larnu關於性能的評論是一個很好的觀點,通常我會避免使用WHILE循環,而應該考慮基於集合的操作,因此,這里是沒有循環且沒有“ FOR XML PATH”的解決方案

    SET NOCOUNT ON
    IF OBJECT_ID ('tempdb..#t1') IS NOT NULL DROP TABLE #T1
    IF OBJECT_ID ('tempdb..##T2') IS NOT NULL DROP TABLE ##T2
    IF OBJECT_ID ('tempdb..##Table') IS NOT NULL DROP TABLE ##Table

    CREATE TABLE #t1 (UserName VARCHAR(100), Company VARCHAR(100));
    INSERT #t1 values ('User1','Company1');
    INSERT #t1 values ('User1','Company2');
    INSERT #t1 values ('User1','Company3');
    INSERT #t1 values ('User1','Company4');
    INSERT #t1 values ('User2','Company3');
    INSERT #t1 values ('User2','Company6');
    INSERT #t1 values ('User2','Company1');
    INSERT #t1 values ('User2','Company5');
    GO

    CREATE TABLE ##Table (UserName nvarchar(50), Combined nvarchar(4000))

    SELECT DENSE_RANK () OVER (ORDER BY UserName) Seq,  *
    INTO ##T2
    FROM #t1

    DECLARE @cmd NVARCHAR(MAX) =''
    ;WITH T2 (Seq) AS 
    (
    SELECT DISTINCT Seq 
    FROM ##T2
    )


    SELECT @cmd += 'DECLARE @ConcatedCompany'+CONVERT(VARCHAR(10),Seq)+' NVARCHAR(4000) = '''' 
                    SELECT @ConcatedCompany'+CONVERT(VARCHAR(10),Seq)+' += '','' + Company FROM ##T2 WHERE Seq = '+CONVERT(VARCHAR(10),Seq)+ CHAR(10)+
                    ' INSERT INTO ##Table (UserName, Combined)
                    SELECT UserName , STUFF(@ConcatedCompany'+CONVERT(VARCHAR(10),Seq)+',1,1,'''') 
                    FROM ##T2 WHERE Seq = '+CONVERT(VARCHAR(10),Seq) + CHAR(10)+
                    ' GROUP BY UserName '+CHAR(10)+
                    ';'
                    +CHAR(10)
     FROM T2


     EXEC sp_executesql  @Cmd

     SELECT UserName , Combined 
     FROM ##Table

     DROP TABLE ##Table
     DROP TABLE ##T2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM