【问题标题】:Update rows returned by a SELECT statement更新 SELECT 语句返回的行
【发布时间】:2015-01-12 08:57:41
【问题描述】:

我有一个复杂的(*)SQL SELECT 语句,它返回我需要更新的行

如何仅更新SELECT 语句返回的行?

我看到的所有关于使用 SELECT 语句更新行的帖子都谈到了使用字段匹配的另一个表的 INNER JOIN (How do I UPDATE from a SELECT in SQL Server?)

我的说法是

SELECT * FROM table1 I 
INNER JOIN
(SELECT *
  FROM (
                SELECT  INTNO,EFFDTE,
                        ROW_NUMBER() OVER(PARTITION BY INTNO,EFFDTE ORDER BY EFFDTE DESC) rn
                    FROM table2 WHERE REFID = 8888 AND EFFDTE IS NOT NULL AND INTNO <> 1234567
              ) a
WHERE rn = 1) X
ON X.INTNO = I.MEMBNO AND I.ENDDTE = DATEADD(DD,-1,X.EFFDTE)
WHERE I.ENDRSN = 'abc'

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    使用这个语法

    UPDATE a
    SET    a.col1 = b.col1,
           a.col1 = b.col2
           .....
           .....
    FROM   update_table a
           JOIN(SELECT *
                FROM   table1 I
                       INNER JOIN (SELECT INTNO,
                                          EFFDTE,
                                          Row_number()
                                            OVER(
                                              PARTITION BY INTNO, EFFDTE
                                              ORDER BY EFFDTE DESC) rn
                                   FROM   table2
                                   WHERE  REFID = 8888
                                          AND EFFDTE IS NOT NULL
                                          AND INTNO <> 1234567) X
                               ON X.INTNO = I.MEMBNO
                                  AND I.ENDDTE = Dateadd(DD, -1, X.EFFDTE)
                WHERE  I.ENDRSN = 'abc'
                       AND rn = 1) b
             ON a.common_colum = b.common_colum 
    

    【讨论】:

    • 谢谢。如果我没有公共列会怎样?即:一个只出现在我的 SELECT 语句返回的行中的值?我的 SELECT 语句可能返回具有 INTNO 111222 的 10 行中的 3 行,但我只想更新其中 3 行,而不是全部 10
    • 谢谢@NoDisplayName - 我意识到我的 SELECT 语句就是答案。我试图将我的整个 select 语句加入到更新中,而我需要稍微退后一步并针对它使用更新。 (我已经添加了答案)
    【解决方案2】:

    这是一个方法和理解如何最好地处理 SQL 查询的问题。

    我不需要加入我构建的整个 SELECT,我只需要将 SELECT 替换为 UPDATE 目标,以便针对更新的联接使用逻辑(和公共列)

    UPDATE table1
    SET field1 = 'MP', field2 = NULL
    FROM 
    table1 I JOIN
    (SELECT *
      FROM (
                    SELECT  INTNO,EFFDTE,
                            ROW_NUMBER() OVER(PARTITION BY INTNO,EFFDTE ORDER BY EFFDTE DESC) rn
                        FROM table2 WHERE REFID = 8888 AND EFFDTE IS NOT NULL AND INTNO <> 1234567
                  ) a
    WHERE rn = 1) X
    ON X.INTNO = I.MEMBNO AND I.ENDDTE = DATEADD(DD,-1,X.EFFDTE)
    WHERE I.ENDRSN = 'abc'
    

    【讨论】:

      【解决方案3】:

      试试这个

      Update table1 
      set Col_Name=Value
      FROM table1 I 
      INNER JOIN
      (SELECT *
        FROM (
                      SELECT  INTNO,EFFDTE,
                              ROW_NUMBER() OVER(PARTITION BY INTNO,EFFDTE ORDER BY EFFDTE DESC) rn
                          FROM table2 WHERE REFID = 8888 AND EFFDTE IS NOT NULL AND INTNO <> 1234567
                    ) a
      WHERE rn = 1) X
      ON X.INTNO = I.MEMBNO AND I.ENDDTE = DATEADD(DD,-1,X.EFFDTE)
      WHERE I.ENDRSN = 'abc'
      

      【讨论】:

      • 欢迎堆栈溢出,这不是答案,您可以将此添加为评论,请机智,直到您从该网站获得至少 50 名评论。
      • 就是这个答案。请检查
      • 请再看一遍,我放了一些文字
      • 好的,我有疑问。你所说的价值是什么意思?
      • 是的看答案Update table1 set Col_Name=Value FROM table1 I INNER JOIN (SELECT * FROM ( SELECT INTNO,EFFDTE, ROW_NUMBER() OVER(PARTITION BY INTNO,EFFDTE ORDER BY EFFDTE DESC) rn FROM table2 WHERE REFID = 8888 AND EFFDTE IS NOT NULL AND INTNO &lt;&gt; 1234567 ) a WHERE rn = 1) X ON X.INTNO = I.MEMBNO AND I.ENDDTE = DATEADD(DD,-1,X.EFFDTE) WHERE I.ENDRSN = 'abc'
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 2016-07-02
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      相关资源
      最近更新 更多