如何将所有文本行值转换为 SQL Server 中的列

Posted

技术标签:

【中文标题】如何将所有文本行值转换为 SQL Server 中的列【英文标题】:How to convert all Text Row values to column in SQL Server 【发布时间】:2020-09-19 07:14:13 【问题描述】:

我在所有文本中都有每个销售员的客户和城市数据。看起来像

Salesman|customer_name|City
Adam| Alex|New york
Adam|Kevin|New york
Adam|Erin|Chicago
Adam|Jim|Los Angeles
Adam|James|New York
Pam|Tod|New York
Pam|Kelly|Chicago
Pam|Rick|Chicago
Lewis|David|Los Angeles
Lewis|Mike|Los Angeles

我需要转置 city 列以按城市获取客户名称以供销售人员使用,这应该类似于 SQL Server 中的样子。我不确定我是否可以在 Pivot 中执行此操作,或者是否有其他选项

Salesman|New york|Chicago|Los Angeles
Adam|Alex|Erin|Jim
Adam|Kevin|NULL|NULL
Adam|James|NULL|NULL
Pam|Tod|Kelly|NULL
Pam|NULL|Rick|NULL
Lewis|NULL|NULL|David
Lewis|NULL|NULL|Mike

【问题讨论】:

【参考方案1】:

这有点棘手,因为当每个城市有多个客户时,您想为每个销售员创建几行。一种方法是先枚举子查询中的行,然后再聚合:

select salesman, 
    max(case when city = 'New York' then customer_name end) new_york,
    max(case when city = 'Chicago' then customer_name end) chicago,
    max(case when city = 'Los Angeles' then customer_name end) los_angeles,
from (
    select t.*, row_number() over(partition by salesman, city order by customer_name) rn
    from mytable t
) t
group by salesman, rn

【讨论】:

【参考方案2】:

一个选项可能是使用条件聚合

select salesmane, 
max(case when city='New york' then customer_name end) as 'New York',
max(case when city='Chicago' then customer_name end) as 'Chicago',
max(case when city='Los Angeles' then customer_name end) as 'Los Angeles'
from t
group by salesman

或者你可以使用 pivot -

select salesman,piv.* from
t pivot
(max(customer_name) for city in([New York],[Chicago],[Los Angeles])) as piv

【讨论】:

我尝试了第一个查询,但值重复。我在查询 salesman|New York|Chicago|Los Angeles D1|1|2|3 D2|1|2|3 D3|1|2|3 D4|1|NULL|NULL D5|1|NULL|NULL 中取了 ID D6|1|NULL|NULL D7|NULL|NULL|3 D8|NULL|NULL|3 @user14304399 你把id列放在group by了吗?【参考方案3】:

使用pivotrow_number 可以得到预期的结果,

这里的诀窍是@GMB 提到的row_number,无论您使用aggregation 还是pivot,它都很有用

select Salesman
      ,[New York]
      ,[Chicago]
      ,[Los Angeles]
  from
(
select t.salesman
      ,t.customer_name
      ,t.city
      ,row_number() over (partition by salesman,city order by customer_name) rn
  from table1 t
) p
pivot
(
 max(customer_name)
 for city in ([New York]
             ,[Chicago]
             ,[Los Angeles])
) c
order by salesman

【讨论】:

以上是关于如何将所有文本行值转换为 SQL Server 中的列的主要内容,如果未能解决你的问题,请参考以下文章

SQL server v17:如何将 smalldatetime 值转换为 datetime

将 SQL Server 日期时间转换为 Int

VBA宏在Excel中格式化1个包含文本行的单元格,并将这些行添加到单独的行中

如何将 DateTime 的 SQL Server XML 类型值 (xsi:nil) 转换为 null

SQL Server 2008 R2 - 将列转换为行并将所有值放在一列中

如何在SQL Server中将datetime值转换为yyyymmddhhmmss?