Sql server SQL-获取具有最大值的列的索引

Sql server SQL-获取具有最大值的列的索引,sql-server,Sql Server,我有一个表,其中包含如下示例数据 col1 col2 col3 4 6 9 7 1 5 我想得到列的索引,该列的值与该行的最大值匹配,如果它们相等,则忽略后面的值 例如,结果应该是return 3 (because col3 has maximum value 9) 1 (because col1 has maximum value 7) 请注意,列数未定义,因此我需要一个通用解决方案 谢谢试试这样的 select case wh

我有一个表,其中包含如下示例数据

col1    col2    col3
4       6       9
7       1       5

我想得到列的索引,该列的值与该行的最大值匹配,如果它们相等,则忽略后面的值

例如,结果应该是return

3 (because col3 has maximum value 9)
1 (because col1 has maximum value 7)
请注意,列数未定义,因此我需要一个通用解决方案


谢谢

试试这样的

select 
case when col1 >= col2 and col1 >= col3 then 1
     when col2 >= col1 and col2 >= col3 then 2
  else 3 end as [index]
from myquestion_table

请参见

您可以这样做:

select case 
           when col1 >= col2 and col1 >= col3 then 1
           when col2 >= col1 and col2 >= col3 then 2
           when col3 >= col1 and col3 >= col2 then 3
        end as ColIndex
from table
试试这个:

select case 
     when col1 >= col2 and col1 >= col3 then 1
     when col2 >= col1 and col2 >= col3 then 2
     else 3
     end as ind
from mytable

这是一个非常基本的示例,但可能类似于:

select case when col1 > col2 and col1 > col3 then col1
       when col2> col3 then col2
       else col3 end as greatestColumn
   from table

一个更通用的解决方案(即N列)是将列解压成行,然后可以应用窗口功能来获得每组列“行”的分组最大值。但是,您需要为每一行使用某种类型的键,以便可以按行方式应用最大值,以允许重新组合原始行。我通过newId添加了一个代理Guid来实现这一点。注意:这将返回每行中具有最高值的列名:

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
编辑,re只是'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;

试试这个,不带枢轴

-可以添加N个列

CREATE TABLE Table1
    ([id] int primary key identity(1,1),[col1] int, [col2] int, [col3] int)
;

INSERT INTO Table1
    ([col1], [col2], [col3])
VALUES
    (4, 6, 9),
    (7, 1, 5)
;

这是另一个pivot解决方案,它比另一个pivot解决方案略短:

DECLARE @t table
(col1 int, col2 int, col3 int)
INSERT @t 
SELECT 4,8,9 union all SELECT 7,1,5 

;WITH addrownumber AS
(
  SELECT 
    rn = row_number() over (order by (select 1)),
    *
  FROM @t
)
, unpiv AS
(
  SELECT 
    rn, 
    value, 
    colname, 
    ordinalposition = row_number() over (partition by rn order by (select 1)),
    rn2 = row_number() over (partition by rn order by value DESC, rn)
  FROM addrownumber as p  
  UNPIVOT
  (value FOR colname IN           
  ([col1], [col2], [col3])) AS unpvt  
  -- since you need all columns to be mentioned in pivot, you can set up
  --  the ordinal order here, by putting in columns in the right order.
)
SELECT ordinalposition, value, colname
FROM unpiv
WHERE rn2 = 1
结果:

ordinalposition value   colname
3               9       col3
1               7       col1

如果他们相等,你想要什么?如果他们相等,就忽略后者。你不需要有第三个,而是写其他:是的,但是这样所有的答案都是一样的:我的不同@GiorgiNakeuri-那么你应该使用IIF:我想,如果OP的最新评论是相等的,就忽略后面的评论,你应该改为>>以选择第一列。@GiorgiNakeuri,谢谢你指出这一点;顺便说一句,OP什么时候评论过。。。我没看到。是的,我现在看到了;编辑问题以包含该点。再次感谢。对不起,我编辑了我的问题以包含未定义的列数。你能修改你的答案吗?如果col的名字是:SomeCol OtherCol WhatCol,这将不起作用。你的答案看起来不错。但是我只需要索引1而不是col1。你能修改你的答案吗?@YukiSakura我有-第二个查询将返回该列的序号。创建表时,您需要防止对DDL的更改,并防止对列结构的DDL修改。@StuartLC:我访问了SQL FIDLE示例。结果是1,3,而它应该是3,1。有什么不对劲吗?@YukiSakura你需要一些东西来点餐,我们可以帮你解决问题。你现在得到的是餐桌的自然顺序,可以是任何东西。为什么不向表中添加一个标识列来替换newid呢
ordinalposition value   colname
3               9       col3
1               7       col1