如何将多行数据放入不同的列

时间:2017-01-05 22:39:16

标签: sql sql-server

我有一个存储帐户ID和值的表。一个帐户可以有多行,每行一个值。我正在尝试创建一个查询,每个帐户ID会给我一行,每个值都有一列(限制为3个值)

数据表样本:

AccountID                               Value
8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB    34CD2F7D-E146-457E-B524-298D15EE0063
8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB    4FC58366-C797-4CAB-8A90-FE7425C1EDCD
8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB    10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC            
02423075-6C7D-4AEB-AE8C-059E43914D53    8327537F-B0CB-43A4-B9BC-31E0A6377F99            
02423075-6C7D-4AEB-AE8C-059E43914D53    2EE12215-AF0D-4636-9E37-7F49EDA22AFF            
BEE8C007-ECA3-4327-8248-A1A66925EE9E    8FC3D058-0AC8-4295-A34D-28755DB52F54            

这是我到目前为止提出的查询:

SELECT C1.AccountId, C1.Value Value1, C2.Value Value2, C3.Value Value3
FROM
TempTable C1
JOIN
TempTable C2 ON C2.AccountId = C1.AccountId AND C2.Value != C1.Value
JOIN
TempTable C3 ON C2.AccountId = C3.AccountId AND C3.AccountId = C1.AccountId AND C3.Value != C2.Value AND C3.Value != C1.Value

以下是我遇到的问题:

  1. 当我使用一个帐户运行查询时,我获得了150条记录。如果我在select语句中放入DISTINCT,它会返回6条记录。
  2. 当我运行distinct时,它会为每个可能的组合创建一行。我不关心值列的位置。
  3. 使用DISTINCT输出(只有一个帐户 - 每个帐户都会有一行):

    AccountId                                      Value1                                      Value2                                      Value3
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB           34CD2F7D-E146-457E-B524-298D15EE0063        4FC58366-C797-4CAB-8A90-FE7425C1EDCD        10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB           34CD2F7D-E146-457E-B524-298D15EE0063        10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC        4FC58366-C797-4CAB-8A90-FE7425C1EDCD
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB           4FC58366-C797-4CAB-8A90-FE7425C1EDCD        34CD2F7D-E146-457E-B524-298D15EE0063        10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB           4FC58366-C797-4CAB-8A90-FE7425C1EDCD        10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC        34CD2F7D-E146-457E-B524-298D15EE0063
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB           10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC        34CD2F7D-E146-457E-B524-298D15EE0063        4FC58366-C797-4CAB-8A90-FE7425C1EDCD
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB           10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC        4FC58366-C797-4CAB-8A90-FE7425C1EDCD        34CD2F7D-E146-457E-B524-298D15EE0063
    

    所需结果(只有一个帐户 - 每个帐户都会有一行):

    AccountId                              Value1                                 Value2                                 Value3
    8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB   34CD2F7D-E146-457E-B524-298D15EE0063   4FC58366-C797-4CAB-8A90-FE7425C1EDCD   10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC  
    

4 个答案:

答案 0 :(得分:0)

请看一下这个链接:数据透视表 http://sqlmag.com/t-sql/create-pivoted-tables-3-steps

答案 1 :(得分:0)

如果您想尝试透视表的替代方法,请编辑您的选择以确保c1.value最小,并且c2.value> c1.value和c3.value> c2.value 对不起,我现在没有ssms来编写和测试代码

答案 2 :(得分:0)

不确定,如果这是你的目标

WITH cte as
(
SELECT '8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB' ID , '34CD2F7D-E146-457E-B524-298D15EE0063' Value UNION ALL
SELECT '8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB' ID , '4FC58366-C797-4CAB-8A90-FE7425C1EDCD' Value UNION ALL
SELECT '8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB' ID , '10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC' Value UNION ALL
SELECT '02423075-6C7D-4AEB-AE8C-059E43914D53' ID , '8327537F-B0CB-43A4-B9BC-31E0A6377F99' Value UNION ALL
SELECT '02423075-6C7D-4AEB-AE8C-059E43914D53' ID , '2EE12215-AF0D-4636-9E37-7F49EDA22AFF' Value UNION ALL
SELECT 'BEE8C007-ECA3-4327-8248-A1A66925EE9E' ID , '8FC3D058-0AC8-4295-A34D-28755DB52F54' Value )
select c1.ID,c1.Value Value_1 ,c2.value 
INTO #temp
from cte c1 inner join cte c2 on c1.ID=c2.ID


WITH BaseQuery AS (
select ID,Value,Value_1 from #temp
)
SELECT ID,
[10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC] V1,
[2EE12215-AF0D-4636-9E37-7F49EDA22AFF] V2,
[34CD2F7D-E146-457E-B524-298D15EE0063] V3,
[4FC58366-C797-4CAB-8A90-FE7425C1EDCD] V4,
[8327537F-B0CB-43A4-B9BC-31E0A6377F99] V5,
[8FC3D058-0AC8-4295-A34D-28755DB52F54] V6
FROM BaseQuery 
PIVOT(max(value_1) FOR Value in (
[10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC],
[2EE12215-AF0D-4636-9E37-7F49EDA22AFF],
[34CD2F7D-E146-457E-B524-298D15EE0063],
[4FC58366-C797-4CAB-8A90-FE7425C1EDCD],
[8327537F-B0CB-43A4-B9BC-31E0A6377F99],
[8FC3D058-0AC8-4295-A34D-28755DB52F54])) AS PVT

答案 3 :(得分:0)

使用PIVOT和条件聚合来实现数据透视有很多资源。我更喜欢使用条件聚合,因为它更清晰,更容易阅读(恕我直言)。

您的案例中唯一不同的是您使用GUID(UNIQUEIDENTIFIER),在使用之前必须将其转换为其他数据类型(例如VARCHAR(50)MAX()

每个AccountID只有三个值,这是使用条件聚合实现所需目标的一种方法:

DECLARE @myTable TABLE (AccountID UNIQUEIDENTIFIER, Value UNIQUEIDENTIFIER);

INSERT @myTable (AccountID, Value)
VALUES ('8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB','34CD2F7D-E146-457E-B524-298D15EE0063'),
       ('8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB','4FC58366-C797-4CAB-8A90-FE7425C1EDCD'),
       ('8CD291F7-1A7E-409B-8D4C-7BECEE5DEBFB','10C64CEE-E026-4197-8BC9-CF5B0EE8ADBC'),    
       ('02423075-6C7D-4AEB-AE8C-059E43914D53','8327537F-B0CB-43A4-B9BC-31E0A6377F99'),
       ('02423075-6C7D-4AEB-AE8C-059E43914D53','2EE12215-AF0D-4636-9E37-7F49EDA22AFF'),
       ('BEE8C007-ECA3-4327-8248-A1A66925EE9E','8FC3D058-0AC8-4295-A34D-28755DB52F54');

SELECT AccountID,
       Value1 = MAX(CASE WHEN RN = 1 THEN Value END),
       Value2 = MAX(CASE WHEN RN = 2 THEN Value END),
       Value3 = MAX(CASE WHEN RN = 3 THEN Value END)
FROM
(
    SELECT AccountID,
           Value = CONVERT(VARCHAR(50), Value), -- Cast GUID as VARCHAR(50) to use MAX() in the outer query.
           RN = ROW_NUMBER() OVER (PARTITION BY AccountID ORDER BY Value)
    FROM @myTable
) T
GROUP BY AccountID;