UPDATE 语句忽略 INNER JOIN

问题描述 投票:0回答:1

我希望 SQL 语句更新有限数量的行,而不是每一行:

UPDATE  Join_Test_1
SET     ANumber = 3
FROM                Join_Test_1 AS ST1
        INNER JOIN  Join_Test_2 AS ST2
        ON          ST1.PKID = ST2.PKID;

我希望该声明的行为与以下声明相同:

UPDATE  Join_Test_1
SET     ANumber = 3
FROM    Join_Test_2
WHERE   Join_Test_1.PKID = Join_Test_2.PKID;

UPDATE  Join_Test_1
SET     ANumber = 3
WHERE   EXISTS (SELECT * FROM Join_Test_2 WHERE Join_Test_2.PKID = Join_Test_1.PKID);
SELECT * FROM Join_Test_1 ORDER BY PKID;

使用 WHERE 子句的语句仅更新 PKID 匹配的“ANumber”字段。 使用 INNER JOIN 的语句更新表中的所有字段。

为什么INNER JOIN不限制更新的行数? 可以重写带有INNER JOIN的语句,使用JOIN来限制更新的行数吗?

/* Expansive Example */
CREATE TABLE Join_Test_1 (PKID SERIAL,ANumber INTEGER);
CREATE TABLE Join_Test_2 (PKID SERIAL,ANumber INTEGER);

INSERT INTO Join_Test_1 (ANumber) VALUES (1),(1);       
INSERT INTO Join_Test_2 (ANumber) VALUES (2);       

UPDATE  Join_Test_1
SET     ANumber = 3
FROM                Join_Test_1 AS ST1
        INNER JOIN  Join_Test_2 AS ST2
        ON          ST1.PKID = ST2.PKID; -- Updates 2
SELECT * FROM Join_Test_1 ORDER BY PKID;
-- 1, 3
-- 2, 3
UPDATE  Join_Test_1 SET ANumber = 1; -- Update 2

UPDATE  Join_Test_1
SET     ANumber = 3
FROM    Join_Test_2
WHERE   Join_Test_1.PKID = Join_Test_2.PKID;
SELECT * FROM Join_Test_1 ORDER BY PKID;
-- 1, 1
-- 2, 3     
UPDATE  Join_Test_1 SET ANumber = 1; -- Update 2
UPDATE  Join_Test_1
SET     ANumber = 3
WHERE   EXISTS (SELECT * FROM Join_Test_2 WHERE Join_Test_2.PKID = Join_Test_1.PKID);
SELECT * FROM Join_Test_1 ORDER BY PKID;
-- 1, 1
-- 2, 3     

DROP TABLE IF EXISTS Join_Test_1;
DROP TABLE IF EXISTS Join_Test_2;
sql postgresql join inner-join
1个回答
1
投票

plpgSQL
中有一种在连接期间更新单个表的方法,如下所示:

CREATE TABLE Join_Test_1 (PKID SERIAL,ANumber INTEGER);
CREATE TABLE Join_Test_2 (PKID SERIAL,ANumber INTEGER);

INSERT INTO Join_Test_1 (ANumber) VALUES (1),(1);       
INSERT INTO Join_Test_2 (ANumber) VALUES (2); 

select * from Join_Test_1;
-- 1    1
-- 2    1

select * from Join_Test_2;
-- 1    2

WITH TT AS (
    UPDATE Join_Test_1
    SET ANumber = 3
    RETURNING *
)
SELECT *
FROM TT          AS ST1
INNER JOIN 
     Join_Test_2 AS ST2
ON   ST1.PKID = ST2.PKID;
-- 1    3   1   2

SELECT * FROM Join_Test_1 ORDER BY PKID;
-- 1    3
-- 2    3

Process-01:db<>fiddle - 加入期间更新

Process-02:db<>fiddle - 正常方式

© www.soinside.com 2019 - 2024. All rights reserved.