SQL 将一行转换为具有未知数量的不同值的列
SQL transforming one row to columns with unknown number of distinct values
我有以下数据库
id item_id date system_code value
#1 0001 01-01-2019 0999 10
#2 0001 02-01-2019 0888 15
#3 0001 01-01-2019 0999 10
#4 0002 02-01-2019 0777 20
#5 0002 03-01-2019 0777 35
我想要实现的结果看起来像这样,system_code 列的值是“值”
的总和
item_id date 0999 0888 0777
0001 01-01-2019 20
0001 02-01-2019 15
0002 02-01-2019 20
0002 03-01-2019 35
我的问题是 system_code 有超过 1000 个不同的值,所以我无法手动输入它们。
数据库有近十亿个条目,所以任何能快速计算的东西都是完美的。
您可以使用条件聚合:
select item_id, date,
max(case when system_code = '0999' then value end) as value_0999,
max(case when system_code = '0888' then value end) as value_0888,
max(case when system_code = '0777' then value end) as value_0777
from t
group by item_id, date;
您可以使用查询生成此 max()
表达式:
select distinct
replace('max(case when system_code = '<val>' then value end) as value_<val>,',
'<val>', system_code
)
from t;
以防万一,这里有一个动态 PIVOT
例子
Declare @SQL varchar(max) = stuff((Select distinct ',' + QUOTENAME([system_code])
From YourTable
Order By 1 Desc
For XML Path('') )
,1,1,'')
Set @SQL = '
Select *
From ( Select item_id,date,system_code,value from YourTable ) src
Pivot ( sum(value) for system_Code in ( '+ @SQL + ') ) pvt
'
--Print @SQL
Exec(@SQL)
Returns
注:
我相信最大列数是 1,024(宽 table 30,000)。
就个人而言,我不希望消耗超过 50 列。
编辑:
如果您有两列,您可以通过在第一个查询中添加 WHERE 来过滤列表,也许 运行 两次(或更多)。结果将具有相同的行数,只是不同的列集。
例子
Declare @SQL varchar(max) = stuff((Select distinct ',' + QUOTENAME([system_code])
From #YourTable
Where [system_code] >'0500' -- or any appropriate filter
Order By 1 desc
For XML Path('') )
,1,1,'')
我有以下数据库
id item_id date system_code value
#1 0001 01-01-2019 0999 10
#2 0001 02-01-2019 0888 15
#3 0001 01-01-2019 0999 10
#4 0002 02-01-2019 0777 20
#5 0002 03-01-2019 0777 35
我想要实现的结果看起来像这样,system_code 列的值是“值”
的总和 item_id date 0999 0888 0777
0001 01-01-2019 20
0001 02-01-2019 15
0002 02-01-2019 20
0002 03-01-2019 35
我的问题是 system_code 有超过 1000 个不同的值,所以我无法手动输入它们。 数据库有近十亿个条目,所以任何能快速计算的东西都是完美的。
您可以使用条件聚合:
select item_id, date,
max(case when system_code = '0999' then value end) as value_0999,
max(case when system_code = '0888' then value end) as value_0888,
max(case when system_code = '0777' then value end) as value_0777
from t
group by item_id, date;
您可以使用查询生成此 max()
表达式:
select distinct
replace('max(case when system_code = '<val>' then value end) as value_<val>,',
'<val>', system_code
)
from t;
以防万一,这里有一个动态 PIVOT
例子
Declare @SQL varchar(max) = stuff((Select distinct ',' + QUOTENAME([system_code])
From YourTable
Order By 1 Desc
For XML Path('') )
,1,1,'')
Set @SQL = '
Select *
From ( Select item_id,date,system_code,value from YourTable ) src
Pivot ( sum(value) for system_Code in ( '+ @SQL + ') ) pvt
'
--Print @SQL
Exec(@SQL)
Returns
注:
我相信最大列数是 1,024(宽 table 30,000)。
就个人而言,我不希望消耗超过 50 列。
编辑:
如果您有两列,您可以通过在第一个查询中添加 WHERE 来过滤列表,也许 运行 两次(或更多)。结果将具有相同的行数,只是不同的列集。
例子
Declare @SQL varchar(max) = stuff((Select distinct ',' + QUOTENAME([system_code])
From #YourTable
Where [system_code] >'0500' -- or any appropriate filter
Order By 1 desc
For XML Path('') )
,1,1,'')