【问题标题】:SQL Server: How can I group multiple row values into separate columns?SQL Server:如何将多个行值分组到单独的列中?
【发布时间】:2017-08-10 03:20:47
【问题描述】:

我正在尝试创建一个SELECT 查询,它允许我将联系人的多个电话号码组合到单独的列中。

例如,我想要以下

Email  |  Phone  |  ID  |
------------------------|
x@x.com| 555-5555| 001  |
x@x.com| 555-5556| 001  |

改为:

Email  |  Phone  |  Phone2  | Phone3 |  ID  |
--------------------------------------------|
x@x.com| 555-5555| 555-5556 |  NULL  | 001  |

虽然这可能是不好的做法,但严格来说,我可以将结果导出为 CSV,以便将该数据上传到 CRM 系统中,该系统在导入时不允许任何重复。我已经查看了所有内容,似乎找不到处理电话号码的答案,因为MINMAX 只允许两个而不是更多。

最复杂的部分是数据库的结构,并且很可能涉及复杂的查询。这是我到目前为止尝试过的,但只能得到 2 个数字,我需要剩余的列(请记住,我不是 SQL 人):

SELECT DISTINCT
       C.CONTACTID,
       MAX(T.NUMBERVALUE) AS Phone1,
       MIN(T.numbervalue) AS Phone2
FROM TBL_PHONE T
     JOIN TBL_CONTACT C ON C.CONTACTID = T.CONTACTID
     JOIN TBL_EMAIL E ON E.CONTACTID = C.CONTACTID
WHERE T.NUMBERVALUE IS NOT NULL
      AND LEN(T.NUMBERVALUE) > 0
GROUP BY C.CONTACTID;

【问题讨论】:

  • 枢轴或动态枢轴取决于您期望有多少个电话号码?
  • 可以在这里看到类似的用法stackoverflow.com/questions/10715004/…
  • 哇你们真快!我预计总共只有 3 个电话号码。我会调查的。非常感谢你的速度!

标签: sql sql-server


【解决方案1】:

这是一个动态的枢轴方式:

declare @table table (Email varchar(64), Phone varchar(16), ID varchar(3))
insert into @table
values

('x@x.com','555-5555','001'),
('x@x.com','555-5556','001'),
('x@x.com','555-5557','001'),
('x@x.com','555-5558','001'),
('x@xdd.com','333-5556','002'),
('x@xdd.com','444-5556','002'),
('x@xdd.com','777-5556','002')


select
    Email
    ,Phone
    ,ID
    ,row_number() over (partition by ID order by Phone) as RN
into #staging
from 
    @table




DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column 
SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
       + QUOTENAME(RN)
FROM (SELECT DISTINCT RN FROM #staging) AS RN

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
  N'SELECT Email, ID, ' + @ColumnName + '
    FROM #staging
    PIVOT(MAX(Phone) 
          FOR RN IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery

drop table #staging

如果您只期望 3 个,如您所说,您可以跳过动态...

declare @table table (Email varchar(64), Phone varchar(16), ID varchar(3))
insert into @table
values

('x@x.com','555-5555','001'),
('x@x.com','555-5556','001'),
('x@xdd.com','333-5556','002'),
('x@xdd.com','444-5556','002'),
('x@xdd.com','777-5556','002')

;with cte as(
select
    Email
    ,Phone
    ,ID
    ,row_number() over (partition by ID order by Phone) as RN
from 
    @table)

select
    Email
    ,max(case when RN = 1 then Phone end) as Phone1
    ,max(case when RN = 2 then Phone end) as Phone2
    ,max(case when RN = 3 then Phone end) as Phone3
    ,ID
from
    cte
group by
    Email
    ,ID

【讨论】:

  • 我完全被你想出的速度之快所震撼!只是试了一下,我认为这正是我所需要的。非常感谢!
  • 不用担心。我还添加了一个简单的解决方案。
  • 我可以将此解决方案与连接一起使用,对吗?我现在使用您的代码作为模板添加了它们,并且对“cte”是什么感到困惑。我收到了 OutOfMemoryException。唯一的区别是没有声明 @table 并且正在使用我已经拥有的列。
  • @ZacHerman CTE 是 common table expression。您可以使用连接(在 cte 内部和外部)。我不确定您为什么会收到 OutOfMemoryException,但请随时在原始问题中发布您的代码,这次我会看看
  • ^ 没关系.. SSMS 一定发生了一些事情,因为我重新启动并且它正在工作。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2017-05-12
  • 2023-03-09
  • 2020-12-03
  • 2018-05-22
  • 2012-05-19
相关资源
最近更新 更多