我是否需要在条件UPDATE中使用where子句?

时间:2015-03-26 15:58:36

标签: sql sql-server tsql

我们从另一个表中导入了大量数据。现在我正在尝试纠正其中一些。

UPDATE [x10ddata].[dbo].[ResourceTest]
  SET [Country] = (CASE
      WHEN [Country] IN ('Aezerbaijan', 'AZERBIJAN') THEN 'Azerbaijan'
      WHEN [Country] = 'Belgique'    THEN 'Belgium'
      WHEN [Country] = 'China (RPC)' THEN 'China'
      WHEN [Country] = 'Columbia'    THEN 'Colombia'
     WHEN [Country] = 'Croatia (Local Name: Hrvatska)' THEN 'Croatia'
     .....//...
     WHEN [Country] IN ('U.S.', 'U.S.A', 'U.S.A.', 'US', 'USA', 
                         'USA - Maryland', 'USAQ') THEN 'United States'
    END)   
  GO

我没有使用 ELSE ,因为很多行都有效国家/地区。我的问题是要知道是否需要 WHERE 子句来过滤受影响的行?

我问这个问题的原因是,我已经选择了一个测试表并尝试了该脚本。根据输出,所有行都受影响,但是当我仔细检查时,并非所有行都受到影响。这令人困惑。

感谢您的帮助

5 个答案:

答案 0 :(得分:3)

如果未满足case条款,null语句将返回when。您可以使用这个简单的SQL验证这一点:

declare @i int
set @i = 2
select case when @i = 1 then 'A' end AS Column1

这将返回null,因为@i不是1

要在您的情况下解决此问题,您可以像您所说的那样添加where子句,或者更简单的选项可能是在所有ELSE [Country]子句之后添加WHEN。这意味着“如果我不需要更改国家/地区字段,那么只需使用之前的相同值。”

答案 1 :(得分:2)

您不需要WHERE子句,但需要ELSE子句。将您的陈述更改为:

UPDATE [x10ddata].[dbo].[ResourceTest]
  SET [Country] = (CASE
      WHEN [Country] IN ('Aezerbaijan', 'AZERBIJAN') THEN 'Azerbaijan'
      WHEN [Country] = 'Belgique'    THEN 'Belgium'
      WHEN [Country] = 'China (RPC)' THEN 'China'
      WHEN [Country] = 'Columbia'    THEN 'Colombia'
     WHEN [Country] = 'Croatia (Local Name: Hrvatska)' THEN 'Croatia'
     .....//...
     WHEN [Country] IN ('U.S.', 'U.S.A', 'U.S.A.', 'US', 'USA', 
                         'USA - Maryland', 'USAQ') THEN 'United States'
     ELSE [Country]
    END)

分享并享受。

答案 2 :(得分:1)

可选地,

制作转化表

DECLARE @conversion TABLE
(
    [Before] NVARCHAR(250) NOT NULL,
    [After] NVARCHAR(250) NOT NULL
);

INSERT @conversion
VALUES
('Aezerbaijan', 'Azerbaijan'),
...
('USAQ', 'United States');

然后呢,

UPDATE [x10ddata].[dbo].[ResourceTest]
            SET [Country] = [C].[After]
    FROM
            [x10ddata].[dbo].[ResourceTest]
        JOIN
            @conversion [C]
                ON [C].[Before] = [C].[Country];

与扩展CASE方法相比,这有许多潜在的性能优势,其中只会影响需要更改的行。

可能值得使用临时表而不是表变量,并在[Before]上创建索引以优化连接。

答案 3 :(得分:0)

不,你不需要where子句,因为你的CASE语句包含你的逻辑。

注意:如果某个值与您的任何CASE语句都不匹配,那么它将返回null。所以我建议最后添加ELSE [Country]。这是一个展示我所说的

的例子
SELECT * INTO #yourTable
FROM
(
    SELECT 1 ID, CAST('OldValue' AS VARCHAR(25)) val
    UNION ALL
    SELECT 2 , 'OldValue'
    UNION ALL
    SELECT 3,'Doesnt need to be updated'
) A

SELECT *
FROM #yourTable;

结果:

ID          val
----------- -------------------------
1           OldValue
2           OldValue
3           Doesnt need to be updated

现在更新:

UPDATE #yourTable
SET val = 
    CASE 
        WHEN ID = 1 THEN 'NewValue1'
        WHEN ID = 2 THEN 'NewValue2'
        --Add this so you leave values alone if they don't match your case statements
        ELSE val
    END
FROM #yourTable


SELECT *
FROM #yourTable

结果:

ID          val
----------- -------------------------
1           NewValue1
2           NewValue2
3           Doesnt need to be updated

答案 4 :(得分:0)

不,你不需要它。除了通过额外(不必要的)写入磁盘和锁定(阻止其他会话)可能产生的性能成本之外,物理结果也是相同的。

有人可能会说你应该使用WHERE子句,不仅是出于性能原因,而是为了更好地捕获和表达意图。