我有一个包含样本数据的表格如下.
col1 col2 col3
4 6 9
7 1 5
Run Code Online (Sandbox Code Playgroud)
我想得到列的索引,其值与该行的最大值匹配,如果它们相等,则忽略后者.
例如,结果应该是return
3 (because col3 has maximum value 9)
1 (because col1 has maximum value 7)
Run Code Online (Sandbox Code Playgroud)
请注意,列数未定义,因此我需要一般解决方案.
谢谢
对此的更通用的解决方案(即 N 列)是将列逆透视为行,然后可以应用窗口函数来获得每组列“行”的分组最大值。然而,每行都需要某种类型的键,以便可以以行方式应用最大值(以允许重新组装原始行)。Guid我通过添加代理来完成此操作newId()。请注意,这将返回每行中具有最高值的列 NAME:
WITH MyTableWithRowId AS
(
SELECT newId() AS Id, *
FROM MyTable
),
Unpivoted AS
(
SELECT Ndx, Id, col, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY col DESC) AS Rnk
FROM
MyTableWithRowId tbl
UNPIVOT
(
col for Ndx in(col1, col2, col3)
) p
)
SELECT Ndx
FROM Unpivoted
WHERE Rnk = 1
Run Code Online (Sandbox Code Playgroud)
编辑,只是“1,2,3”而不是列的名称(col1,col2,col3)
根据 @Giorgi 的评论,如果您确实想要每行中列的(基于一个的)序号位置,您可以重新连接到 DMV,例如INFORMATION_SCHEMA.COLUMNS查找序号,尽管在我看来,这将是非常脆弱的策略。
WITH MyTableWithRowId AS
(
SELECT newId() AS Id, col1, col2, col3
FROM MyTable
),
TheOrdinalPositionOfColumns AS
(
SELECT COLUMN_NAME, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
),
Unpivoted AS
(
SELECT Ndx, Id, col, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY col DESC) AS Rnk
FROM
MyTableWithRowId tbl
UNPIVOT
(
col for Ndx in(col1, col2, col3)
) p
)
SELECT topoc.ORDINAL_POSITION AS ColumnOrdinalPosition
FROM Unpivoted
JOIN TheOrdinalPositionOfColumns topoc ON Unpivoted.Ndx = topoc.COLUMN_NAME
WHERE Rnk = 1;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1219 次 |
| 最近记录: |