更新包含大量案例表达式的查询 - 如何避免空更新?

时间:2015-09-24 09:37:14

标签: sql database postgresql

示例查询

UPDATE table_name tn SET 
        col1 = CASE WHEN col1 = 'x' THEN 'X' WHEN col1 = 'y' THEN 'Y' ELSE 'Z' END,
        col2 = CASE WHEN col2 = 'x' THEN 'X' WHEN col2 = 'y' THEN 'Y' ELSE 'Z' END,
        col3 = CASE WHEN col3 = 'x' THEN 'X' WHEN col3 = 'y' THEN 'Y' ELSE 'Z'
        END
        FROM temp_table tt
        WHERE tn.id = tt.id AND 
    ( col1 IS DISTINCT FROM (CASE WHEN col1 = 'x' THEN 'X' WHEN col1 = 'y' THEN 'Y' ELSE 'Z' END) 
OR col2 IS DISTINCT FROM (CASE WHEN col2 = 'x' THEN 'X' WHEN col2 = 'y' THEN 'Y' ELSE 'Z' END) 
OR (col3 IS DISTINCT FROM (CASE WHEN col3 = 'x' THEN 'X' WHEN col3 = 'y' THEN 'Y' ELSE 'Z' END) )

对于上述查询以避免空更新,我们可以将查询表示为

WITH tmp AS
(
SELECT id, col1 = CASE WHEN col1 = 'x' THEN 'X' WHEN col1 = 'y' THEN 'Y' ELSE 'Z' END,
            col2 = CASE WHEN col2 = 'x' THEN 'X' WHEN col2 = 'y' THEN 'Y' ELSE 'Z' END column2,
            col3 = CASE WHEN col3 = 'x' THEN 'X' WHEN col3 = 'y' THEN 'Y' ELSE 'Z' AS coloumn3
FROM temp_table
)
UPDATE table_name tn SET col1 = tmp.column1, col2 = tmp.column2, col3 = tmp.column3
FROM tmp
WHERE tmp.id = tn.id AND
      (tn.col1 IS DISTINCT FROM tmp.column1 OR
       tn.col2 IS DISTINCT FROM tmp.column2 OR
       tn.col3 IS DISTINCT FROM tmp.column3
      )

有更好的方法吗?

谢谢, 香卡。

1 个答案:

答案 0 :(得分:0)

在Postgres中,您可以使用行构造函数:

WITH tmp AS (
      SELECT id, col1 = CASE WHEN col1 = 'x' THEN 'X' WHEN col1 = 'y' THEN 'Y' ELSE 'Z' END,
             col2 = CASE WHEN col2 = 'x' THEN 'X' WHEN col2 = 'y' THEN 'Y' ELSE 'Z' END column2,
             col3 = CASE WHEN col3 = 'x' THEN 'X' WHEN col3 = 'y' THEN 'Y' ELSE 'Z' AS coloumn3
      FROM temp_table
     )
UPDATE table_name tn
    SET (col1, col2, col3) = (tmp.column1, tmp.column2, tmp.column3
FROM tmp
WHERE tmp.id = tn.id AND
      (tn.col1, tn.col2, tn.col3) IS DISTINCT FROM (tmp.column1, tmp.column2, temp.column3);