这是一个示例表:
Create table #TableA (ID INT
, [1] DECIMAL(6,5)
,[1.1] DECIMAL(6,5)
, [2] DECIMAL(6,5)
,[2.2] DECIMAL(6,5)
, [3] DECIMAL(6,5)
,[3.3] DECIMAL(6,5)
, [4] DECIMAL(6,5)
,[4.4] DECIMAL(6,5)
, FLAGB1 CHAR(1)
, FLAGB2 float)
INSERT INTO #TABLEA (ID, [1],[1.1],[2],[2.2],[3],[3.3],[4],[4.4],FLAGB1,FLAGB2 )
VALUES(1, 1.1111,null, 2.2222,0.1234, 3.3333,null,null, 1.4444,'y',null )
, (2, null,1.2345, 2.2345,null, 3.2345, 4.2345,1.5437,0.2378,null,null)
,(3, 5.3789,1.2222,0.23864,null, 2.2222, 3.2222, 4.2222,null,'y',null)
Drop #TableA
如果FLAGB1为'Y',我需要列FLAGB2来获取“MAX”列名。道歉,我不能更清楚地将要求放在一个句子中,所以结果应该是这样的:
> [ID] [1] [1.1] [2] [2.2] [3] [3.3] [4] [4.4] [FLAGB1] [FLAGB2]
> 1 1.11110 NULL 2.22220 0.12340 3.33330 NULL NULL 1.44440 y 4.4
> 2 NULL 1.23450 2.23450 NULL 3.23450 4.23450 1.54370 0.23780 NULL NULL
> 3 5.37890 1.22220 0.23864 NULL 2.22220 3.22220 4.22220 NULL y 4
答案 0 :(得分:1)
不幸的是,SQL Server没有greatest()
功能。你可以用case
语句来痛苦地做到这一点:
update #tableA
set flagB2 = (case when [1] >= [1.1] and [1] >= [2] and [1] >= [2.2] and
[1] >= [3] and [1] >= [3.3] and [1] >= [4] and [1] >= [4.4]
then 1
when [2] >= [1] and [2] >= [1.1] and and [2] >= [2.2] and
[2] >= [3] and [2] >= [3.3] and [2] >= [4] and [2] >= [4.4]
then 2
. . .
end)
where flagB1 = 'y';
这种类型的数据结构让我怀疑列[1]
- [4.4]
是相关的。这通常意味着您应该有一个关联/联结表,每个id
有一行,每个值都有一行。使用该数据结构编写查询会更容易。
答案 1 :(得分:0)
以下内容允许更改表架构。看起来你可以根据你所展示的内容使用一些容差。我带了一个光标,因为我看不到在“原始”更新语句中使用服务器的反射函数。但我认为它改进了对脚本中的列进行硬编码。
CREATE TABLE #TableA (
ID int PRIMARY KEY,
[1] DECIMAL(6,5),
[1.1] DECIMAL(6,5),
[2] DECIMAL(6,5),
[2.2] DECIMAL(6,5),
[3] DECIMAL(6,5),
[3.3] DECIMAL(6,5),
[4] DECIMAL(6,5),
[4.4] DECIMAL(6,5),
FLAGB1 CHAR(1),
FLAGB2 float)
INSERT INTO #TABLEA (ID,[1],[1.1],[2],[2.2],[3],[3.3],[4],[4.4],FLAGB1,FLAGB2)
VALUES(1, 1.1111,null, 2.2222,0.1234, 3.3333,null,null, 1.4444,'y',null )
, (2, null,1.2345, 2.2345,null, 3.2345, 4.2345,1.5437,0.2378,null,null)
,(3, 5.3789,1.2222,0.23864,null, 2.2222, 3.2222, 4.2222,null,'y',null)
-- The following will run a separate UPDATE statement for every column having a numeric name on the #TableA temp table
-- Get all column names from the temp table (thus tempdb's INFORMATION_SCHEMA) that are numeric and put them in a new temp table, #columns
SELECT Column_Name
INTO #columns
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE '#TableA%'
AND ISNUMERIC(Column_Name) = 1
DECLARE @column_name varchar(80)
-- Create a cursor to loop through the contents of #columns
DECLARE cur_columns CURSOR FOR
SELECT
Column_Name
FROM
#columns
ORDER BY
CONVERT(decimal, Column_Name)
OPEN cur_columns
FETCH NEXT FROM cur_columns INTO @column_name
-- For each numeric column name...
WHILE(@@FETCH_STATUS = 0)
BEGIN
DECLARE @SQL varchar(max)
-- Build an UPDATE statement dynamically
-- Update the FLAGB2 column with the column name for this iteration given the value in that column is not null and FLAGB1 is either 'y' or 'Y'
SET @SQL = '
UPDATE #TableA SET
FLAGB2 = ' + @column_name + '
WHERE
' + QUOTENAME(@column_name) + ' IS NOT NULL
AND UPPER(FLAGB1) = ''Y'''
-- Execute the UPDATE statement
EXEC(@SQL)
FETCH NEXT FROM cur_columns INTO @column_name
END
CLOSE cur_columns
DEALLOCATE cur_columns
SELECT * FROM #TableA