SQL如果行值存在,则创建新列

时间:2019-12-10 18:41:22

标签: sql

我有一个大型数据集,如下所示:

NAME    Value
Dan     1 
Dan     92
Dan     A4
Steve   1
Steve   B10
John    4

我正在尝试将其转换为类似表的内容:

Name    Value1    Value2    Value3
Dan     1         92        B10
Steve   1         B10       Null
John    4         Null      Null

因此行的数量未知,我想为每个值创建一个新列(如果存在)。任何人都知道如何在SQL中执行此操作?

2 个答案:

答案 0 :(得分:0)

您提供的示例在使用PIVOT时可以很好地工作,但是您需要为值提供一个类别以进行数据透视。

例如

NAME    Category    Value
Dan     Value1      1 
Dan     Value2      92
Dan     Value3      A4
Steve   Value1      1
Steve   Value3      B10
John    Value1      4

那么您的结果将是这样

Name    Value1  Value2    Value3
Dan     1       92        A4
Steve   1       NULL      B10
John    4       NULL      NULL

这是Microsoft的文档: https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15

要动态执行此操作,请阅读这篇文章。它很好地处理了相同的情况。 SQL Server dynamic PIVOT query?

答案 1 :(得分:0)

要透视数据,需要一些透视数据。

在这种情况下,可以使用ROW_NUMBER生成它。

例如:

--
-- sample data
-- 
create table yourlargetable (
 id int identity(1,1) primary key,
 name nvarchar(30),
 value nvarchar(30)
);

insert into yourlargetable (name, value) values
('jane', 'val1'), ('jane', 'val2'), ('jane', 'val3'), 
('john', 'val4'), ('john', 'val5');

--
-- declare a few variables
--
declare @DynSql nvarchar(max);
declare @Cols nvarchar(max);
declare @ColTotal int;

--
-- how many columns are needed
-- 
select top 1 @ColTotal = count(*)
from yourlargetable
group by name 
order by count(*) desc;

--
-- generate a string with column names
--
with RCTE_NUMS as
(
  select 1 as n
  union all
  select n+1
  from RCTE_NUMS
  where n < @ColTotal
)
select @Cols = concat(@Cols+', ', quotename(concat('Value', n)))
from RCTE_NUMS
order by n;

--
-- create the dynamic sql string
-- 
set @DynSql = 'select *'+ char(10) +
'from ('+
'select name, value '+ char(10) +
', concat(''Value'', row_number() over (partition by name order by value)) col '+ char(10) +
'from yourlargetable) s'+ char(10) +
'pivot (max(value) '+ char(10) +
'for col in ('+ @Cols +')) p'+ char(10) +
'order by name';

-- select @DynSql;

--
-- run the dynamic sql
-- 
exec sp_executesql @DynSql;

返回:

name    Value1  Value2  Value3
jane    val1    val2    val3
john    val4    val5    NULL