在 SQL 中反透视表时获取值存在的列的位置

Posted

技术标签:

【中文标题】在 SQL 中反透视表时获取值存在的列的位置【英文标题】:get the positon of a column where value exists while unpivoting the table in SQL 【发布时间】:2019-01-24 06:27:24 【问题描述】:

我试图在 SQL Server 中对 col2、col3、col4 列进行反透视时获取值的列位置

df1
col1     col2     col3     col4     
1        AAA      BBB
2        ABC      CCC      DDD

result
col1     [All]     [position]
1        AAA        1
1        BBB        2
2        ABC        1
2        CCC        2
2        DDD        3

我可以使用以下方法取消透视表

SELECT a.col1, a.[all]
from df1 as t
UNPIVOT
(
[all] for col_nm in (
    col2, col3, col4
) as a

【问题讨论】:

你是如何在 col1 上得到 3 的?请也提供你的逻辑 @Avi,抱歉打错了。我不确定您所说的逻辑是什么意思,但我提供了有关如何取消透视表的代码 尝试阅读此link 它可能会对您有所帮助。 :) 【参考方案1】:

如果您只需要知道它来自哪一列,我认为您可以简单地将 col_nm 包含到您的 select 语句中:

SELECT a.col1
      ,a.[all]
      ,a.col_nm
FROM   df1 AS t UNPIVOT([all] FOR col_nm IN(col2, col3, col4)) AS a;

如果您需要知道列索引号——那么根据上面的说明应该很容易——也许对列名进行 switch-case 检查;或者,

如果这是物理表或临时表,您可以使用 sys.tables 和 sys.columns 重新连接,以根据列名查找列索引 (columnId)。

【讨论】:

【参考方案2】:

您可以在下面尝试 - 使用 row_number()

SELECT a.col1, a.[all],row_number() over(partition by a.col1 order by a.[all]) as position
from df1 as t
UNPIVOT
(
[all] for col_nm in (
    col2, col3, col4
) as a

【讨论】:

这似乎不起作用 - 使用 OrderBy 时,row_number() 可能无法为您提供正确的列索引... @Rex,你最好试一试,告诉我它行不通 好的,我现在试了一下,确认它不起作用 - 您可以在将第一个值“AAA”调整为“ZZZ”后尝试查询,您将看到列号变为 3 ,因为排序是最后一个!【参考方案3】:

试试这个

select * from (

select col1,1 as position , col2  as [All] from [Table] 
Union
select col1,2 as position, col3  as [All] from [Table] 
Union
select col1,3 as position, col4  as [All] from [Table] )
where [all] is not null;


【讨论】:

【参考方案4】:

你可以使用APPLY

SELECT df1.col1, dff.*     
FROM df1 as df CROSS APPLY
     ( VALUES (col2, 1), (col3, 2), (col4, 3) ) dff([All], [Position])
WHERE dff.[All] IS NOT NULL;

【讨论】:

以上是关于在 SQL 中反透视表时获取值存在的列的位置的主要内容,如果未能解决你的问题,请参考以下文章

在 PostgreSQL 中反透视数据

sql server 反透视表

在 sql 中创建一个带联接的数据透视表

Excle数据透视如何创建多条件汇总的数据透视表

带有文本值的 SQL Server 数据透视表

在子查询中为数据透视列的值实现 WHERE 子句?