2017-02-14 72 views
2

我有2个SQL表,其中一个表包含源列和目标列,另一个表包含源值的转换逻辑。我需要应用转换逻辑并更新目标列。基于SQL存储在另一列的SQL Server更新列

表1

ID | PreVal |PostVal 
1 | 5 | 
1 | 6 | 
1 | 7 | 
2 | 10 | 
2 | 15 | 

表2 - 转换逻辑

ID | Logic 
1 | case when PreVal < 6 then 1 else 0 end 
2 | case when PreVal < 12 then 1 else 0 end 

是否可以通过连接两个表(而不是通过在通过每个ID去构建动态SQL都只是一个普通的更新语句光标)实现以下输出

ID | PreVal |PostVal 
1 | 5 | 1 
1 | 6 | 0 
1 | 7 | 0 
2 | 10 | 1 
2 | 15 | 0 

为您的H非常感谢ELP。

+2

_通过连接两个表(而不是通过遍历游标中的每个ID构建动态SQL)来实现下面的输出_否可能只有一个通用更新语句,您需要为此使用动态sql。 – Tanner

+0

如果您更改逻辑表数据,使其只具有PreVal的值(第一个表的值必须小于),那么是的。但是,你无法按照原样对转换表进行任何操作。 – Matthew

+0

@Tanner我不介意动态SQL,但我不希望在游标中通过ID来标识ID,因为此表利用了列存储索引。 –

回答

0

把你的逻辑为正式表中,然后加入:

UPDATE t1 
SET PostVal = CASE WHEN t1.PreVal < t2.PreVal 
        THEN t2.positive ELSE t2.negative END 
FROM Table1 t1 
INNER JOIN 
(
    SELECT 1 AS ID, 6 AS PreVal, 1 AS positive, 0 AS negative 
    UNION ALL 
    SELECT 2, 12, 1, 0 
) t2 
    ON t1.ID = t2.ID 
+0

我想我应该提到,我有大约一百万条记录,有近1000个转换逻辑,因此需要一个单独的“逻辑表” –

0

你可以尝试这样的事情:

WITH query as 
(
    select 1 as id, 6 as 'preval_max', 1 as 'then_result', 0 as 'end_result' union 
    select 2 as id, 12 as 'preval_max', 1 as 'then_result', 0 as 'end_result' 
) 
UPDATE Table1 
SET PostVal = case when Table1.preval < query.preval_max then query.then_result else query.end_result end 
FROM Table1 
inner join query 
    on Table1.id = query.id 

查询的栏目让你有不同的逻辑。

0

如果您的转换逻辑太复杂,如:

1 case when PreVal < 6 then 1 else 0 end 
2 case when PreVal = 0 then 1 else 2 end 
3 case when PreVal > 1000 then 0 else 1 end 
4 case when PreVal = 1 then 1 else 2 end 

那么我相信没有什么你可以做。

在这种情况下,我会跑:

select distinct 
    'update table1 set PostVal = ' + b.Logic + ' where Id = ' + convert (varchar(10), a.id) 
from 
    table1 a 
    inner join table2 b on (a.id = b.id) 

产生更新语句的每一行和分段运行它们。

+0

这将产生不正确的结果 – balaji

+0

@balaji我纠正了我的答案。 – shadow