根据唯一值将多行数据选择为一行

时间:2014-02-16 00:11:37

标签: sql-server

我想在一行中选择多行数据。

我正在使用的数据有两列:

  • 贷款号码
  • 名称

贷款编号附加的每个名称都有不同的行。

示例:

  

贷款号码1有3个不同的名称,因此贷款号码有3行,每个名称一个。

我想要做的是,获取每个不同的名称并为其分配一个新列,这样每个贷款号码就有一个唯一的行,每个不同的名称都附加在它们自己的列中,而不是每个名称都有一行。

这是否可以使用分区在选择状态下完成?

2 个答案:

答案 0 :(得分:0)

我不认为你会用纯SQL来做这件事。我尝试使用存储过程,例如创建临时表。我认为你必须动态构建一个字符串来让sqlserver执行,以创建表。然后你可以对它进行更新,最后使用select返回单行。

您是否会尝试返还多笔贷款,每行一笔(尽管每个贷款的贷款名称各不相同)?因为如果贷款一个有三个名字而贷款二有四个名字,那就不会在同一张表中找到。

如何将所有名称打包成第二列的竖线分隔字符串,以及第一列中的贷款号码?可能仍然需要存储过程,但它比创建不同数量的列容易得多。然后在数据库的客户端管道上拆分以获取名称。

答案 1 :(得分:0)

您可以使用动态支点执行此操作,虽然您的列名称将成为用户名,但如果您在c#中处理输出,则这不是什么大问题;你可以迭代一个字段数。一个问题是如果你有两个名字相同的用户,他们只会显示一次。

Here's a great SO post on dynamic pivots

使用这种方法,我想出了下面的示例代码。 (注意行SET @loanID = 1 - 在1和2之间切换以测试输出)

IF OBJECT_ID('TEMPDB..#LOANS') IS NOT NULL
    DROP TABLE #LOANS

CREATE TABLE #LOANS (LOANID INT, USERNAME NVARCHAR(100))

INSERT INTO #LOANS 
SELECT 1, 'Neal' UNION ALL
SELECT 1, 'Bob' UNION ALL
SELECT 2, 'Sarah' UNION ALL
SELECT 2, 'John' UNION ALL
SELECT 2, 'Elsa' UNION ALL
SELECT 2, 'Jennifer' UNION ALL
SELECT 2, 'Dave'


DECLARE @cols AS NVARCHAR(MAX), @y AS INT, @sql AS NVARCHAR(MAX), @loanID INT

-- set an id here...
SET @loanID = 1

SET @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT USERNAME AS y
        FROM #LOANS
        WHERE LOANID=@loanID) AS Y
ORDER BY y
FOR XML PATH('')),
1, 1, N'');

SET @sql = N'SELECT *
FROM (SELECT LOANID, USERNAME 
      FROM #LOANS 
      WHERE LOANID='+CAST(@loanID AS NVARCHAR)+') AS D
PIVOT(MIN(USERNAME) FOR USERNAME IN(' + @cols + N')) AS P;';

EXEC sp_executesql @sql;
GO

如果你有一个userID,你的结果可能会是这样的:

IF OBJECT_ID('TEMPDB..#LOANS') IS NOT NULL
    DROP TABLE #LOANS

CREATE TABLE #LOANS (LOANID INT, USERNAME NVARCHAR(100), USERID INT)

INSERT INTO #LOANS 
SELECT 1, 'Neal', 1 UNION ALL
SELECT 1, 'Bob', 2 UNION ALL
SELECT 2, 'Sarah', 3 UNION ALL
SELECT 2, 'John', 4 UNION ALL
SELECT 2, 'Elsa', 5 UNION ALL
SELECT 2, 'Jennifer', 6 UNION ALL
SELECT 2, 'Dave', 7


DECLARE @cols AS NVARCHAR(MAX), @y AS INT, @sql AS NVARCHAR(MAX), @loanID INT

-- set an id here...
SET @loanID = 1

SET @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT USERID AS y
        FROM #LOANS
        WHERE LOANID=@loanID) AS Y
ORDER BY y
FOR XML PATH('')),
1, 1, N'');

SET @sql = N'SELECT *
FROM (SELECT LOANID, USERNAME, USERID
      FROM #LOANS 
      WHERE LOANID='+CAST(@loanID AS NVARCHAR)+') AS D
PIVOT(MIN(USERNAME) FOR USERID IN(' + @cols + N')) AS P;';

EXEC sp_executesql @sql;
GO