带有 WHERE EXISTS 的 SQL UPDATE 语句

Posted

技术标签:

【中文标题】带有 WHERE EXISTS 的 SQL UPDATE 语句【英文标题】:SQL UPDATE statement with WHERE EXISTS 【发布时间】:2012-01-26 19:15:52 【问题描述】:

我正在尝试编写一个查询,仅当我正在更新的组的 LINE_CD 为 50 时才更新日期。我会这样做吗?

UPDATE EMPLOYER_ADDL  
SET EMPLOYER_ADDL.GTL_UW_APPRV_DT = EMPLOYER_ADDL.DNTL_UW_APPRV_DT 
WHERE EXISTS
    ( 
      SELECT EMP_PLAN_LINE_INFO.LINE_CD
      FROM EMP_PLAN_LINE_INFO
      Where EMP_PLAN_LINE_INFO.GR_NBR = EMPLOYER_ADDL.GR_NBR and
       EMP_PLAN_LINE_INFO.LINE_CD = 50
     )

【问题讨论】:

你有很多“正确答案”,祝你好运。 【参考方案1】:
UPDATE ea
  SET GTL_UW_APPRV_DT = DNTL_UW_APPRV_DT
  FROM EMPLOYER_ADDL AS ea
  WHERE EXISTS
  (
    SELECT 1
      FROM EMP_PLAN_LINE_INFO AS ep
      WHERE ep.GR_NBR = ea.GR_NBR
      AND ep.LINE_CD = 50
  );

但是,如果您可以从查询中获取此信息,为什么还要更新表?似乎这必须不断运行,否则可能会过时。

【讨论】:

您应该明确提及列名。如果将来更改架构怎么办?所以应该是列名而不是 1... @***User - 这个实例没关系。他正在使用1,因为EXISTS 短路,我们实际上并没有返回该字段。我们只想知道,一行是否满足列出的条件? 在 EXISTS 内部,列名无关紧要。您可以说 *、NULL、'constant' 等。 1 不是列名。如果架构发生变化并且您在其中提到了一个明确的列名,那不是 less 不会过时吗? @*** 用户,我给出了在我投反对票时我反对你的答案的原因。您缺少“FROM”,并且不需要“SET”中的别名或表名。请不要在其他人的回答中询问有关您的回答的问题。 @BillOrtell 该语法适用于 Oracle,但不适用于 SQL Server。【参考方案2】:

这个怎么样?

UPDATE ea  
SET ea.GTL_UW_APPRV_DT = ea.DNTL_UW_APPRV_DT 
FROM EMPLOYER_ADDL ea
    INNER JOIN EMP_PLAN_LINE_INFO ei ON(ei.GR_NBR = ea.GR_NBR)
WHERE 
ei.LINE_CD = 50

【讨论】:

唯一的问题是,如果连接产生重复项(例如,如果 GR_NBR 在 EMPLOYER_ADDL 或 EMP_PLAN_LINE_INFO 中不是唯一的),则需要额外的工作。我认为 EXISTS 格式更安全,因为它可以满足这两种情况。 YMMV。 GR_NBR 在 EPLI 表中不是唯一的,但它在 ADDL 中。通过额外的工作,您是否意味着查询需要更长的时间才能运行?【参考方案3】:

我相信这会给你同样的结果。

UPDATE ea
  SET GTL_UW_APPRV_DT = DNTL_UW_APPRV_DT
  FROM EMPLOYER_ADDL AS ea
  INNER JOIN EMP_PLAN_LINE_INFO AS ep
      ON ep.GR_NBR = ea.GR_NBR
      AND ep.LINE_CD = 50

【讨论】:

请拒绝投票的原因,以便我了解我做错了什么。 我没有投反对票,但我认为无论是谁投的票,可能是因为你的原始格式不好?我们在同一时间发布了几乎相同的内容,所以我不知道您为什么投了反对票。 我从记事本复制了它。当我添加答案时,它搞砸了格式。无论如何继续前进.. 欢呼伙计们。【参考方案4】:

假设 GR_NBR 是一个 PK 并且在 EMP_Plan_line_Info 中是不同的:

UPDATE  EA
SET     GTL_UW_APPRV_DT = DNTL_UW_APPRV_DT
FROM    EMPLOYER_ADDL EA
        INNER JOIN EMP_PLAN_LINE_INFO EP
            ON EP.GR_NBR = EA.GR_NBR
               AND EP.LINE_CD = 50

【讨论】:

【参考方案5】:

也试试这个。我认为这对你来说是新的?

UPDATE ADDL   
SET ADDL.GTL_UW_APPRV_DT = ADDL.DNTL_UW_APPRV_DT 
From EMPLOYER_ADDL ADDL
Inner Join  EMP_PLAN_LINE_INFO INFO on INFO.GR_NBR = ADDL.GR_NBR
Where INFO.LINE_CD = 50

【讨论】:

No FROM,并且您不需要 ADDL。在 SET ADDL.GTL_UW_APPRV_DT = @DanAndrews 个人而言,我更喜欢明确。将别名放在SET 行有什么危害?这对于阅读您的代码但不知道别名并非绝对必要的同事很有帮助。如果您使用合理的别名,它应该有助于更好地记录代码,而不是使其阅读和理解更加麻烦。 @Aaron Bertrand,您正在设置您要更新的内容,没有什么可弄清楚的。投反对票的主要原因是缺少 FROM,现在已将其修改为包含。 @AaronBertrand 我看不到在 SET 行上有别名有任何价值。它不像它可以更新任何其他表。 这是主观的。你看不到任何价值,我看不到任何伤害。对于不了解 SQL Server 专有的 UPDATE FROM 语法的初级人员来说,使用别名更好地记录它是没有争议的。想象一个连接到 15 个表的更新,并且集合的右侧来自不同的表。我发现明确的价值。如果你不这样做,好的。【参考方案6】:

我相信存在需要通配符:

UPDATE EMPLOYER_ADDL  
SET EMPLOYER_ADDL.GTL_UW_APPRV_DT = EMPLOYER_ADDL.DNTL_UW_APPRV_DT 
WHERE EXISTS
    ( 
      SELECT *
      FROM EMP_PLAN_LINE_INFO
      Where EMP_PLAN_LINE_INFO.GR_NBR = EMPLOYER_ADDL.GR_NBR and
       EMP_PLAN_LINE_INFO.LINE_CD = 50
     )

不过,我更喜欢使用 IN。有人认为它可能会更慢,但我发现 2005 年及更高版本的 SQL 优化器使 IN 的工作方式与 EXISTS 相同,如果该字段是非空字段。

UPDATE EMPLOYER_ADDL  
SET EMPLOYER_ADDL.GTL_UW_APPRV_DT = EMPLOYER_ADDL.DNTL_UW_APPRV_DT 
WHERE EMPLOYER_ADDL.GR_NBR IN
    ( 
      SELECT EMP_PLAN_LINE_INFO.GR_NBR
      FROM EMP_PLAN_LINE_INFO
      Where EMP_PLAN_LINE_INFO.LINE_CD = 50
     )

【讨论】:

不,EXISTS 不需要通配符。优化器完全忽略列列表。 点了。我见过的所有存在的例子都有一个通配符,但我从来没有彻底测试过它。我注意到你的回答只是做了一个选择 1.. 有趣。 WHERE 通配符是 %,SELECT 通配符是 *。引用所有字段。

以上是关于带有 WHERE EXISTS 的 SQL UPDATE 语句的主要内容,如果未能解决你的问题,请参考以下文章

SQL 中 EXISTS 与 NOT EXISTS

Oracle where exists 子句不适用于 SQL Plus

带有 Exists 的 WHERE CASE WHEN THEN 语句

使用 SQL Where Exists() 过滤结果

带有“where exists”的“Set”比没有的效果更好

sql 中exists 在where中怎样用?