我有一個包含示例數據的表,如下所示。SQL - 獲取具有最大值的列的索引
col1 col2 col3
4 6 9
7 1 5
我想有值的最大數值匹配該行,如果他們是平等的,只是忽略了後列的索引。
舉例來說,結果應該是返回
3 (because col3 has maximum value 9)
1 (because col1 has maximum value 7)
請注意,列數是不確定的,所以我需要一個通用的解決方案。
謝謝
我有一個包含示例數據的表,如下所示。SQL - 獲取具有最大值的列的索引
col1 col2 col3
4 6 9
7 1 5
我想有值的最大數值匹配該行,如果他們是平等的,只是忽略了後列的索引。
舉例來說,結果應該是返回
3 (because col3 has maximum value 9)
1 (because col1 has maximum value 7)
請注意,列數是不確定的,所以我需要一個通用的解決方案。
謝謝
的更通用的解決方案(即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
編輯,重新只是 '1,2,3' 不是列名(COL1,COL2,COL3 )
按@的Giorgi的評論,如果你真的想每行中的列(一個基於)序號位置,你可以加入回DMV的如INFORMATION_SCHEMA.COLUMNS
查找序,雖然這將是可怕的脆弱的戰略IMO。
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;
如果列名是'SomeCol OtherCol WhatCol',這將不起作用。 http://sqlfiddle.com/#!6/4b7bc/1 –
你的答案看起來不錯。不過,我只需要索引(1而不是col1)。你能修改你的答案嗎? – YukiSakura
@YukiSakura我有 - 第二個查詢將返回列的序數。在創建表時,您需要防止對DDL進行更改,並防止對列結構進行DDL修改。 – StuartLC
你可以這樣說:
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
你不需要有第三個'時'而不是寫'else' :) –
是的,但這種方式所有的答案將是相同的:)我的是不同的! –
我喜歡與衆不同! ;)+1 –
試試這個:
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個列。
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)
;
DECLARE @tempTable as table(name varchar(50),maxValue int)
DECLARE @maxColumn int
SELECT @maxColumn = max(ordinal_position)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'Table1'
DECLARE @maxRow int
SELECT @maxRow = Count(col1) FROM Table1
DECLARE @rowCounter int = 1
DECLARE @colCounter int = 1
DECLARE @columnName varchar(max)
DECLARE @colValue varchar(max)
DECLARE @q nvarchar(max)
DECLARE @maxValue int
DECLARE @ParmDefinition nvarchar(500)
DECLARE @FinalResult table (id int, columnName nvarchar(max))
DECLARE @rowId int
WHILE(@rowCounter <= @maxRow)
BEGIN
WHILE (@colCounter <= @maxColumn)
BEGIN
SELECT @columnName = COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'Table1' and ordinal_position = @colCounter
--select @columnName,@rowCounter,@colCounter
SELECT @q = 'select @retvalOUT =' + @columnName + ' from Table1 where id = ' + cast(@rowCounter as NVARCHAR)
SET @ParmDefinition = N'@retvalOUT int OUTPUT';
EXEC sp_executesql @q,@ParmDefinition ,@retvalOUT = @maxValue OUT
--select '@maxValue' + @maxValue
INSERT INTO @tempTable VALUES (@columnName,@maxValue)
SET @colCounter = @colCounter + 1
END
SELECT @rowId = maxValue FROM @tempTable WHERE name LIKE 'id' -- Primary key column
INSERT INTO @FinalResult(id,columnName)
SELECT TOP 1 @id,name FROM @tempTable WHERE name not like 'id' ORDER BY maxvalue DESC
DELETE FROM @tempTable
--select * from @FinalResult
SET @colCounter = 1
SET @rowCounter = @rowCounter + 1
END
SELECT * FROM @FinalResult
這裏是另一個支點的解決方案,它比其他支點的解決方案更短一點:
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
如果他們是平等的什麼你要嗎? –
如果他們是平等的,只是忽略後者。 – YukiSakura