SQL查询-行到列不是真正的轴
我试图将ID的某些字段移动到列中,但它似乎与我找到的所有pivot示例都不匹配。我能找到的所有示例都使用某种形式的字段值分组。无论字段中的值如何,我都希望使用更多的位置。我希望在查询中不通过代码进行循环SQL查询-行到列不是真正的轴,sql,sql-server,pivot,Sql,Sql Server,Pivot,我试图将ID的某些字段移动到列中,但它似乎与我找到的所有pivot示例都不匹配。我能找到的所有示例都使用某种形式的字段值分组。无论字段中的值如何,我都希望使用更多的位置。我希望在查询中不通过代码进行循环数据源示例(很抱歉,在文章中无法确定如何格式化表格,因此我使用了一段代码片段): 我试图生成的结果集: +----+------+------+-------+------+------+------+ | ID | Col1 | Col2 | Col3 | Col4 | Col5 | Col6
数据源示例(很抱歉,在文章中无法确定如何格式化表格,因此我使用了一段代码片段): 我试图生成的结果集:
+----+------+------+-------+------+------+------+
| ID | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 |
+----+------+------+-------+------+------+------+
| 1 | NULL | NULL | | | | |
| 2 | Jim | 321 | Jack | 54 | Sue | 985 |
| 3 | Herb | 332 | Chevy | 10 | | |
+----+------+------+-------+------+------+------+
SQL Fiddle:
解释
ROW_NUMBER()(按字段1、字段2按id顺序划分)r
。这一行确保每个id
都有一个从1开始计数的列。这使我们能够区分多行
CTE
用于保存为c1
、c2
和c3
键入的相同语句
联接确保一行中的所有项具有相同的id,并且col1、col3和col5的数据(同样,col2、col4和col6的数据)取自连续的行。我们使用的是left-outer
联接,因为源表中可能没有这些列的行
where
语句表示为c1
中的数据获取每组3的第一行(由于前面的联接,c2
和c3
因此是每组的第二行和第三行)。SQL Fiddle:
解释
ROW_NUMBER()(按字段1、字段2按id顺序划分)r
。这一行确保每个id
都有一个从1开始计数的列。这使我们能够区分多行
CTE
用于保存为c1
、c2
和c3
键入的相同语句
联接确保一行中的所有项具有相同的id,并且col1、col3和col5的数据(同样,col2、col4和col6的数据)取自连续的行。我们使用的是left-outer
联接,因为源表中可能没有这些列的行
where
语句要求为c1
中的数据获取每组3的第一行(由于前面的连接,c2
和c3
因此是每组的第二行和第三行)。这里有一个使用动态sql的解决方案,虽然我相信有更好的方法可以做到这一点。小心,有点痛。首先,它构建要透视和选择的列列表,构建动态sql并运行它
DECLARE @PivotColumns as varchar(max), @SelectColumns as varchar(max), @sql as varchar(max)
SELECT @PivotColumns = ISNULL(@PivotColumns + ',', '') + ColNum,
@SelectColumns = ISNULL(@SelectColumns + ',', '') + 'NULLIF(' + ColNum + ', ''NULL'') as ' + ColNum
from (select distinct 'Col' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as ColNum
from (select id,
isnull(field1,'NULL') as field1,
isnull(field2,'NULL') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) unpivoted) DistinctColumns
set @sql = '
select id, + ' + @SelectColumns + '
from (select
''Col'' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as colnum
,id
,value
from (select id,
isnull(field1,''NULL'') as field1,
isnull(field2,''NULL'') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) u) unpivoted
pivot
(
max(value)
for colnum in (' + @PivotColumns + ')
) p'
exec (@sql)
这里有一个使用动态sql的解决方案,虽然我相信有更好的方法可以做到这一点。小心,有点痛。首先,它构建要透视和选择的列列表,构建动态sql并运行它
DECLARE @PivotColumns as varchar(max), @SelectColumns as varchar(max), @sql as varchar(max)
SELECT @PivotColumns = ISNULL(@PivotColumns + ',', '') + ColNum,
@SelectColumns = ISNULL(@SelectColumns + ',', '') + 'NULLIF(' + ColNum + ', ''NULL'') as ' + ColNum
from (select distinct 'Col' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as ColNum
from (select id,
isnull(field1,'NULL') as field1,
isnull(field2,'NULL') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) unpivoted) DistinctColumns
set @sql = '
select id, + ' + @SelectColumns + '
from (select
''Col'' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as colnum
,id
,value
from (select id,
isnull(field1,''NULL'') as field1,
isnull(field2,''NULL'') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) u) unpivoted
pivot
(
max(value)
for colnum in (' + @PivotColumns + ')
) p'
exec (@sql)
如果一行(2,Kramer,13)突然出现,您希望发生什么?这是一个轴心,您只需要在多个列上轴心。您使用的是什么数据库?此外,对于第一个表示例,您的ID显示重复的值。是否也有每行唯一的自动增量列?如果是这样的话,那么它是什么呢?我希望Col7和Col8会出现在high hair.bluefeet-sqlserver中,但是可能会有50000个不同的id。再说一次,我没有很好地理解枢轴。如果突然出现一个(2,Kramer,13)行,你会期望发生什么?这是一个枢轴,你只需要在多个列上进行枢轴。您使用的是什么数据库?此外,对于第一个表示例,您的ID显示重复的值。是否也有每行唯一的自动增量列?如果是这样的话,那么它是什么呢?我希望Col7和Col8会出现在high hair.bluefeet-sqlserver中,但是可能会有50000个不同的id。再说一次,我对支点没有很好的把握。
DECLARE @PivotColumns as varchar(max), @SelectColumns as varchar(max), @sql as varchar(max)
SELECT @PivotColumns = ISNULL(@PivotColumns + ',', '') + ColNum,
@SelectColumns = ISNULL(@SelectColumns + ',', '') + 'NULLIF(' + ColNum + ', ''NULL'') as ' + ColNum
from (select distinct 'Col' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as ColNum
from (select id,
isnull(field1,'NULL') as field1,
isnull(field2,'NULL') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) unpivoted) DistinctColumns
set @sql = '
select id, + ' + @SelectColumns + '
from (select
''Col'' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as colnum
,id
,value
from (select id,
isnull(field1,''NULL'') as field1,
isnull(field2,''NULL'') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) u) unpivoted
pivot
(
max(value)
for colnum in (' + @PivotColumns + ')
) p'
exec (@sql)