如何根据某列合并来自不同行的某些数据?

时间:2015-01-30 15:39:45

标签: sql sql-server tsql

我有一个看起来像这样的表:

--------------------------------
  | name | email      | friend |
--------------------------------
1 | bob  | bobs email | kate   |
--------------------------------
2 | bob  | bobs email | joe    |
--------------------------------
3 | tim  | tims email | eddie  |

我如何创建新列(friend1friend2等)并在那里移动朋友,条件是名称和电子邮件相同(例如,可能有两个bobs) bob和bob用不同的电子邮件)。

我想要的表格如下:

-----------------------------------------------------
  | name | email      | friend1 | friend2 | friend3 |
-----------------------------------------------------
1 | bob  | bobs email | kate   | joe      |         |
-----------------------------------------------------
2 | tim  | tims email | eddie  |          |         |

2 个答案:

答案 0 :(得分:1)

这是无法实现的,因为您需要的查询没有静态元数据(即您不知道列),因为如果添加了朋友,它可能会随时间而变化。但是,如果您的意思是只需要三列朋友,则可以使用PIVOT命令。您可以使用以下链接作为示例:

http://blogs.msdn.com/b/spike/archive/2009/03/03/pivot-tables-in-sql-server-a-simple-sample.aspx

另一个解决方案(遗憾的是,在SQL Server中不容易使用)是聚合朋友,即您只有一列包含所有朋友,无论他们的计数如何,并用逗号分隔。这可以使用CLR函数(示例:http://www.mssqltips.com/sqlservertip/2022/concat-aggregates-sql-server-clr-function/),CTE(示例:Optimal way to concatenate/aggregate strings)或FOR XML(示例:Does T-SQL have an aggregate function to concatenate strings?)来实现。

希望这会有所帮助......

答案 1 :(得分:0)

拥有这些样本数据:

DECLARE @DataSource TABLE
(
    [name] VARCHAR(12)
   ,[email] VARCHAR(24)
   ,[friend] VARCHAR(12)
)

INSERT INTO @DataSource ([name], [email], [friend])
VALUES ('bob', 'bobs email', 'kate')
      ,('bob', 'bobs email', 'joe')
      ,('tim', 'tim email', 'edie')

以下查询:

SELECT DD.[name]
      ,DD.[email]
      ,Friends.[friend]
      ,ROW_NUMBER() OVER (PARTITION BY DD.[name], DD.[email] ORDER BY Friends.[friend]) AS [FriendNumber]
FROM 
(
    SELECT DISTINCT [name]
                   ,[email]
    FROM @DataSource
) DD -- Distinct Data
CROSS APPLY
(
    SELECT [friend]
    FROM @DataSource DS
    WHERE  DS.[name] = DD.[name]
        AND DS.[email] = DD.[email]
) Friends

会给你:

enter image description here

所以,您现在可以构建想要使用数据透视表,但请注意,您需要知道一个人可以拥有的最大朋友数量:

SELECT *
FROM
(   
    SELECT DD.[name]
          ,DD.[email]
          ,Friends.[friend]
          ,'friend' + CAST(ROW_NUMBER() OVER (PARTITION BY DD.[name], DD.[email] ORDER BY Friends.[friend]) AS VARCHAR(2)) AS [FriendNumber]
    FROM 
    (
        SELECT DISTINCT [name]
                       ,[email]
        FROM @DataSource
    ) DD -- Distinct Data
    CROSS APPLY
    (
        SELECT [friend]
        FROM @DataSource DS
        WHERE  DS.[name] = DD.[name]
            AND DS.[email] = DD.[email]
    ) Friends
) DS
PIVOT
(
    MAX([friend]) FOR [FriendNumber] IN ([friend1], [friend2], [friend3])
) PVT

enter image description here