使用 LEFT JOIN 和 INNER JOIN 插入

Posted

技术标签:

【中文标题】使用 LEFT JOIN 和 INNER JOIN 插入【英文标题】:Insert using LEFT JOIN and INNER JOIN 【发布时间】:2012-08-17 21:35:24 【问题描述】:

大家好,我想知道如何使用以下查询插入新记录:

SELECT user.id, user.name, user.username, user.email, 
  IF(user.opted_in = 0, 'NO', 'YES') AS optedIn  
FROM 
  user
  LEFT JOIN user_permission AS userPerm ON user.id = userPerm.user_id
ORDER BY user.id;

到目前为止,我的INSERT 查询是这样的:

INSERT INTO user 
SELECT * 
FROM user 
  LEFT JOIN user_permission AS userPerm ON user.id = userPerm.user_id;

但是,当使用左连接和内连接时,我不确定如何处理 VALUE('','','','', etc etc)

所以我想做的是:

User表:

id    | name       | username    | password                 | OptIn
--------------------------------------------------------------------
562     Bob Barker   bBarker       BBarker@priceisright.com   1

还有user_permission

user_id   | Permission_id
-------------------------
562         4

更新 就这样?

INSERT INTO user (name, username, password, email, opted_in) VALUES ('Bbarker','Bbarker','blahblahblah','Bbarker@priceisright.com',0);
INSERT INTO user_permission (user_id, permission_id) VALUES (LAST_INSERT_ID(),4);

【问题讨论】:

当您刚刚从user 中选择了值时,为什么要插入user?您打算插入什么新行? @AaronJSpetner 当您提出修改建议时,请进行完整修改,以便后续修改无需修复大小写、标点符号和删除“大家好”等无用文本。 【参考方案1】:

您必须具体说明您选择的列。如果您的user 表有四列id, name, username, opted_in,您必须从查询中准确选择这四列。语法如下:

INSERT INTO user (id, name, username, opted_in)
  SELECT id, name, username, opted_in 
  FROM user LEFT JOIN user_permission AS userPerm ON user.id = userPerm.user_id

但是,这里似乎没有任何理由反对user_permission,因为该表中的所有列都不会插入user。事实上,这个INSERT 似乎必然会因违反主键唯一性而失败。

mysql 不支持同时插入多个表。您需要在代码中使用第一个查询中的最后一个插入 ID 执行两个 INSERT 语句,或者在主表上创建一个 AFTER INSERT 触发器。

INSERT INTO user (name, username, email, opted_in) VALUES ('a','b','c',0);
/* Gets the id of the new row and inserts into the other table */
INSERT INTO user_permission (user_id, permission_id) VALUES (LAST_INSERT_ID(), 4)

或者使用trigger:

CREATE TRIGGER creat_perms AFTER INSERT ON `user`
FOR EACH ROW
BEGIN
  INSERT INTO user_permission (user_id, permission_id) VALUES (NEW.id, 4)
END

【讨论】:

我需要在 user_permission 表以及用户表旁边插入一行。我该怎么做? 更新了我的 OP 以更好地解释我想要做什么。 @StealthRT 如果没有多个语句或第一个表上的触发器,您无法将新行插入到 2 个表中。 我再次更新了我的 OP,以反映我在想你的帖子的意思。让我知道它是否正确。我需要在两次插入之间运行“更新”吗? @StealthRT 是的,就像那样——但是你必须在第一个之后立即执行第二个,否则LAST_INSERT_ID() 的值将变得无效。 LAST_INSERT_ID() 依赖于连接,因此只要在同一连接上按顺序执行这些操作,您就会得到正确的值。如果在两者之间发生任何其他插入,您将得到错误的值。【参考方案2】:

在使用另一个 SELECT 查询插入数据时,您不能使用 VALUES 子句。见INSERT SYNTAX

INSERT INTO user
(
 id, name, username, email, opted_in
)
(
    SELECT id, name, username, email, opted_in
    FROM user
         LEFT JOIN user_permission AS userPerm
            ON user.id = userPerm.user_id
);

【讨论】:

【参考方案3】:
INSERT INTO Test([col1],[col2]) (
    SELECT 
        a.Name AS [col1],
        b.sub AS [col2] 
    FROM IdTable b 
    INNER JOIN Nametable a ON b.no = a.no
)

【讨论】:

以上是关于使用 LEFT JOIN 和 INNER JOIN 插入的主要内容,如果未能解决你的问题,请参考以下文章

外连接(left join、full join、right join)与内连接(inner join)的区别

sql left join 和 inner join 效率

SQL语句(inner join,left out join,right out join三者的不同

SQL中left join on 、right join on、inner join on之间的区别

inner join left join right join 和full join的区别

inner join和left join right join 的区别?