使用内连接更新 SQL

发布于 2024-12-11 20:45:10 字数 749 浏览 0 评论 0原文

我有一个记录表,它具有自我关系。

另外 - 为了使搜索更容易 - 我有一个标志,它确定一条记录已被引用,因此该行现在“已过时”,并且仅用于审核目的:

CREATE TABLE Records
(
  RecordID INT(5) NOT NULL,
  Replaces INT(5) NULL,
  Obsolete INT(1) NOT NULL
)

RecordID 是 PK,Replaces 链接到现已被替换的先前 RecordID,而 Obsolete 是冗余信息,它只是表示另一条记录已替换了该记录。它只是让搜索变得更加容易。桌子很大。这些只是其中的 3 列。

唯一的问题是:系统中的一个查询存在拼写错误,因此对于一小部分行,Obsolete 值未设置为 1 (true)。

此查询将显示 Obsolete 等于 0 的所有记录,应等于 1:

   SELECT *
     FROM Records AS rec1
LEFT JOIN Records AS rec2
       ON rec1.Replaces = rec2.RecordID
    WHERE rec2.RecordID IS NOT NULL
      AND rec2.Obsolete = 0;

现在我需要运行 UPDATE 将所有这些 req2.Obsolete 从 0 更改为 1,但我不确定如何编写查询内部连接。

I have a table of records, which has a self-relationship.

Additionally - to make searching easier - I have a flag which determines that a record has been referenced and hence that row is now "obsolete" and is only there for audit purposes:

CREATE TABLE Records
(
  RecordID INT(5) NOT NULL,
  Replaces INT(5) NULL,
  Obsolete INT(1) NOT NULL
)

RecordID is the PK, Replaces links to a previous RecordID which has now been replaced, and Obsolete is redundant information which just says that another record has replaced this one. It just makes searching a lot easier. The table is very large. These are just 3 of the columns.

The only problem is: there was a typo in one of the queries in the system so for a small set of rows, the Obsolete value was not set to 1 (true).

This query will show all the records with Obsolete equal to 0 which should be equal to 1:

   SELECT *
     FROM Records AS rec1
LEFT JOIN Records AS rec2
       ON rec1.Replaces = rec2.RecordID
    WHERE rec2.RecordID IS NOT NULL
      AND rec2.Obsolete = 0;

Now I need to run an UPDATE to change all those req2.Obsolete from 0 to 1, but I'm not sure how to write a query with an INNER JOIN.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三人与歌 2024-12-18 20:45:10

您不需要内部联接。由于您的查询已经返回需要更新的记录,只需执行以下操作:

Update Records
set Obsolete=1 where
RecordID in (
 SELECT rec2.RecordID     
        FROM Records AS rec1
LEFT JOIN Records AS rec2
       ON rec1.Replaces = rec2.RecordID
    WHERE rec2.RecordID IS NOT NULL
      AND rec2.Obsolete = 0
)

You don't need an inner join. Since your query already returns the records that need to be updated, just do this:

Update Records
set Obsolete=1 where
RecordID in (
 SELECT rec2.RecordID     
        FROM Records AS rec1
LEFT JOIN Records AS rec2
       ON rec1.Replaces = rec2.RecordID
    WHERE rec2.RecordID IS NOT NULL
      AND rec2.Obsolete = 0
)
樱娆 2024-12-18 20:45:10
UPDATE Records
SET obsolete = 1
WHERE recordID in (
SELECT rec1.recordid
     FROM Records AS rec1
LEFT JOIN Records AS rec2
       ON rec1.Replaces = rec2.RecordID
    WHERE rec2.RecordID IS NOT NULL
      AND rec2.Obsolete = 0
)
UPDATE Records
SET obsolete = 1
WHERE recordID in (
SELECT rec1.recordid
     FROM Records AS rec1
LEFT JOIN Records AS rec2
       ON rec1.Replaces = rec2.RecordID
    WHERE rec2.RecordID IS NOT NULL
      AND rec2.Obsolete = 0
)
缱绻入梦 2024-12-18 20:45:10

我建议使用临时表分两步执行此操作:

-- Create temporary table for holding RecordIDs to be marked as obsolete
CREATE TEMPORARY TABLE `mark_obsolete` (`RecordID` INT NOT NULL);

-- Insert RecordIDs to mark as obsolete into temp table
INSERT INTO `mark_obsolete` (`RecordID`)
SELECT `rec2`.`RecordID`
FROM
    `Records` AS `rec1`
    INNER JOIN `Records` AS `rec2`
        ON `rec1`.`Replaces` = `rec2`.`RecordID`
WHERE `rec2`.`Obsolete` = 0;

-- Update records using inner join to temp table
UPDATE
    `Records` AS `r`
    INNER JOIN `mark_obsolete` AS `o`
        ON `r`.`RecordID` = `o`.`RecordID`
SET `r`.`Obsolete` = 1;

DROP TEMPORARY TABLE `mark_obsolete`;

请注意,使用 LEFT JOINWHERE rec2.RecordID IS NOT NULLINNER 相同加入

使用临时表的原因是为了避免在更新子查询中使用的同一表时出现锁定问题。与使用 IN 子句相比,它还可能为您提供更好的性能。

I would suggest doing this in two steps using a temporary table:

-- Create temporary table for holding RecordIDs to be marked as obsolete
CREATE TEMPORARY TABLE `mark_obsolete` (`RecordID` INT NOT NULL);

-- Insert RecordIDs to mark as obsolete into temp table
INSERT INTO `mark_obsolete` (`RecordID`)
SELECT `rec2`.`RecordID`
FROM
    `Records` AS `rec1`
    INNER JOIN `Records` AS `rec2`
        ON `rec1`.`Replaces` = `rec2`.`RecordID`
WHERE `rec2`.`Obsolete` = 0;

-- Update records using inner join to temp table
UPDATE
    `Records` AS `r`
    INNER JOIN `mark_obsolete` AS `o`
        ON `r`.`RecordID` = `o`.`RecordID`
SET `r`.`Obsolete` = 1;

DROP TEMPORARY TABLE `mark_obsolete`;

Note that using a LEFT JOIN with WHERE rec2.RecordID IS NOT NULL is the same as an INNER JOIN.

The reason for using a temporary table is to avoid locking issues when updating the same table used in the sub-query. And it might also give you better performance than using the IN clause.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文