【问题标题】:concatenating single column in TSQL在 SQL 中连接单个列
【发布时间】:2011-12-01 00:58:23
【问题描述】:

我正在使用 SSMS 2008 并尝试根据不同字段的分组将其中一行连接在一起。我有两列,people_id 和 address_desc。它们看起来像这样:

address_desc                         people_id
----------                           ------------ 
Murfreesboro, TN  37130              F15D1135-9947-4F66-B778-00E43EC44B9E 
11 Mohawk Rd., Burlington, MA 01803  C561918F-C2E9-4507-BD7C-00FB688D2D6E 
Unknown, UN  00000                   C561918F-C2E9-4507-BD7C-00FB688D2D6E        Jacksonville, NC  28546                  FC7C78CD-8AEA-4C8E-B93D-010BF8E4176D 
Memphis, TN  38133                   8ED8C601-5D35-4EB7-9217-012905D6E9F1 
44 Maverick St., Fitchburg, MA       8ED8C601-5D35-4EB7-9217-012905D6E9F1

现在我想连接 address_desc 字段/people_id。所以这里的第一个应该只显示 address_desc 的“Murfreesboro, TN 37130”。但是第二个人应该只有一行,而不是两行,地址描述为“11 Mohawk Rd., Burlington, MA 01803;Unknown, UN 00000”。

我该怎么做?我尝试使用 CTE,但这给了我模棱两可的错误:

WITH CTE ( people_id, address_list, address_desc, length  ) 
          AS ( SELECT people_id, CAST( '' AS VARCHAR(8000) ), CAST( '' AS VARCHAR(8000) ), 0
                 FROM dbo.address_view
                GROUP BY people_id
                UNION ALL
               SELECT p.people_id, CAST( address_list + 
                      CASE WHEN length = 0 THEN '' ELSE ', ' END + c.address_desc AS VARCHAR(8000) ), 
                      CAST( c.address_desc AS VARCHAR(8000)), length + 1
                 FROM CTE c
                INNER JOIN dbo.address_view p
                   ON c.people_id = p.people_id
                WHERE p.address_desc > c.address_desc )
SELECT people_id, address_list 
      FROM ( SELECT people_id, address_list, 
                    RANK() OVER ( PARTITION BY people_id ORDER BY length DESC )
               FROM CTE ) D ( people_id, address_list, rank )
     WHERE rank = 1 ;

这是我最初的 SQL 查询:

SELECT a.address_desc, a.people_id 
FROM dbo.address_view a 
INNER JOIN (SELECT people_id 
FROM dbo.address_view 
GROUP BY people_id 
HAVING COUNT(*) > 1) t 
ON a.people_id = t.people_id 
order by a.people_id

【问题讨论】:

    标签: tsql sql-server-2008 common-table-expression


    【解决方案1】:

    你可以像这样使用FOR XML PATH('')

    DECLARE @TestData TABLE
    (
         address_desc NVARCHAR(100) NOT NULL
        ,people_id UNIQUEIDENTIFIER NOT NULL
    );
    
    INSERT  @TestData 
    SELECT  'Murfreesboro, TN  37130',              'F15D1135-9947-4F66-B778-00E43EC44B9E'
    UNION ALL
    SELECT  '11 Mohawk Rd., Burlington, MA 01803',  'C561918F-C2E9-4507-BD7C-00FB688D2D6E'
    UNION ALL
    SELECT  'Unknown, UN  00000',                   'C561918F-C2E9-4507-BD7C-00FB688D2D6E'
    UNION ALL
    SELECT  'Memphis, TN  38133',                   '8ED8C601-5D35-4EB7-9217-012905D6E9F1'
    UNION ALL
    SELECT  '44 Maverick St., Fitchburg, MA',       '8ED8C601-5D35-4EB7-9217-012905D6E9F1';
    
    SELECT  a.people_id,
        (SELECT SUBSTRING(
            (SELECT ';'+b.address_desc
            FROM    @TestData b 
            WHERE   a.people_id = b.people_id
            FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
            ,2
            ,4000)
        ) GROUP_CONCATENATE
    FROM    @TestData a
    GROUP BY a.people_id
    

    结果:

    people_id                            GROUP_CONCATENATE
    ------------------------------------ ------------------------------------------------------
    F15D1135-9947-4F66-B778-00E43EC44B9E Murfreesboro, TN  37130
    C561918F-C2E9-4507-BD7C-00FB688D2D6E 11 Mohawk Rd., Burlington, MA 01803;Unknown, UN  00000
    8ED8C601-5D35-4EB7-9217-012905D6E9F1 Memphis, TN  38133;44 Maverick St., Fitchburg, MA
    

    【讨论】:

    • 超级!正是我需要的。谢谢!
    猜你喜欢
    • 2021-10-15
    • 2016-12-03
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 2012-11-20
    • 2020-02-10
    相关资源
    最近更新 更多