SQL查询将具有相同姓氏和地址的人放入一行

时间:2012-02-26 02:25:12

标签: sql

假设有一个这样的SQL表:

Label Name | Last name | Address Line 1 | Address line 2
-----------+-----------+----------------+-------------------
John       | Smith     | 100 Any St     | Anytown, WI, 50000
Jane       | Smith     | 100 Any St     | Anytown, WI, 50000
Bill       | Doe       | 200 Any St     | Anytown, WI, 50000
Sam        | Rodgers   | 200 Any St     | Anytown, WI, 50000
Lisa       | Thompson  | 300 Any St     | Anytown, WI, 50000
Walter     | Thompson  | 300 Any St     | Anytown, WI, 50000
Chuck      | Thompson  | 300 Any St     | Anytown, WI, 50000

什么SQL查询会产生这样的表?:

Label Name              | Last name | Address Line 1 | Address line 2
------------------------+-----------+----------------+-------------------
John and Jane           | Smith     | 100 Any St     | Anytown, WI, 50000
Bill                    | Doe       | 200 Any St     | Anytown, WI, 50000
Sam                     | Rodgers   | 200 Any St     | Anytown, WI, 50000
Lisa, Walter, and Chuck | Thompson  | 300 Any St     | Anytown, WI, 50000

2 个答案:

答案 0 :(得分:2)

您应该在表示层中而不是在DBMS中执行这些操作。

但是,如果确实希望在DBMS级别执行此操作,并且您的DBMS是MS SQL Server(正如您的注释所示),则可以执行以下操作:

首先,创建一个连接相关[Label Name]值的函数(使用','和'和'作为分隔符):

CREATE FUNCTION CombineNames (
    @LastName nvarchar(max),
    @AddressLine1 nvarchar(max),
    @AddressLine2 nvarchar(max)
)
RETURNS nvarchar(max) AS
BEGIN

    DECLARE @NameCount INT;

    SELECT @NameCount = COUNT(*)
    FROM YOUR_TABLE
    WHERE
        [Last name] = @LastName
        AND [Address Line 1] = @AddressLine1
        AND [Address line 2] = @AddressLine2;

    DECLARE @List nvarchar(max);

    SELECT
        @List
            = COALESCE(@List, '')
            + (
                CASE ROW_NUMBER() OVER(ORDER BY [Label Name])
                WHEN 1 THEN ''
                WHEN @NameCount THEN ' and '
                ELSE ', '
                END
            )
            + CAST([Label Name] as nvarchar(max))
    FROM YOUR_TABLE
    WHERE
        [Last name] = @LastName
        AND [Address Line 1] = @AddressLine1
        AND [Address line 2] = @AddressLine2
    ORDER BY
        [Label Name];

    RETURN (SELECT @List)

END

然后使用这样的函数:

SELECT
    dbo.CombineNames([Last name], [Address Line 1], [Address Line 2]),
    T.*
FROM
    (
        SELECT DISTINCT [Last name], [Address Line 1], [Address Line 2]
        FROM YOUR_TABLE
    ) T

结果:

(No column name)        Last name       Address Line 1      Address Line 2
----------------        ---------       --------------      --------------
Bill                    Doe             200 Any St          Anytown, WI, 50000
Sam                     Rodgers         200 Any St          Anytown, WI, 50000
Jane and John           Smith           100 Any St          Anytown, WI, 50000
Chuck, Lisa and Walter  Thompson        300 Any St          Anytown, WI, 50000

答案 1 :(得分:1)

没有,这不是sql的工作方式。您需要在SQL或其他语言上进行迭代以对条目进行分组。你可以得到的最近的事情是:

John | Smith | 100 Any St | Anytown, WI, 50000
Jane | Smith | 100 Any St | Anytown, WI, 50000

Bill | Doe | 200 Any St | Anytown, WI, 50000
Sam | Rodgers | 200 Any St | Anytown, WI, 50000

Lisa | Thompson | 300 Any St | Anytown, WI, 50000
Walter | Thompson | 300 Any St | Anytown, WI, 50000
Chuck | Thompson | 300 Any St | Anytown, WI, 50000

您可以使用简单的GROUP BY语句来获取

请注意您如何构建Statement:

SELECT field1, field2, field3 FROM table WHERE field2 = requirement;
          ^       ^      ^
          1       2      3   

您将获得的字段数量是固定的,在这种情况下,3。并且您无法做任何事情来使其有时4或有时5.唯一的变量将是您获得的记录数量,但格式他们的输出是固定的,并由你的查询决定。