66

Hey all i am trying to figure out how to go about inserting a new record using the following query:

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;

My INSERT query so far is this:

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

However, i am not sure how to do VALUE('','','','', etc etc) when using left and inner joins.

So what i am looking to do is this:

User table:

id    | name       | username    | password                 | OptIn
--------------------------------------------------------------------
562     Bob Barker   bBarker       [email protected]   1

And also the user_permission table

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

UPDATE So like this?

INSERT INTO user (name, username, password, email, opted_in) VALUES ('Bbarker','Bbarker','blahblahblah','[email protected]',0);
INSERT INTO user_permission (user_id, permission_id) VALUES (LAST_INSERT_ID(),4);
2
  • 1
    Why are you inserting into user when you have just selected values from user? What new row are you intending to insert? Commented Aug 22, 2012 at 12:53
  • 1
    @AaronJSpetner when you propose an edit, please make it a complete edit so that subsequent edits are not required to fix casing, punctuation, and removal of useless text like "hey all". Commented Jul 8, 2018 at 10:39

3 Answers 3

90

You have to be specific about the columns you are selecting. If your user table had four columns id, name, username, opted_in you must select exactly those four columns from the query. The syntax looks like:

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

However, there does not appear to be any reason to join against user_permission here, since none of the columns from that table would be inserted into user. In fact, this INSERT seems bound to fail with primary key uniqueness violations.

MySQL does not support inserts into multiple tables at the same time. You either need to perform two INSERT statements in your code, using the last insert id from the first query, or create an AFTER INSERT trigger on the primary table.

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)

Or using a 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
5
  • 1
    I am in need of inserting a row in the user_permission table as well along side the user table. How would i do that?
    – StealthRT
    Commented Aug 22, 2012 at 12:58
  • 1
    Updated my OP to better explain what i was looking to do.
    – StealthRT
    Commented Aug 22, 2012 at 13:06
  • 2
    @StealthRT You can't insert new rows into 2 tables without multiple statements, or a trigger on the first table. Commented Aug 22, 2012 at 13:07
  • 1
    I updated my OP again to reflect what i am thinking you mean by your post. Let me know if its correct. Would i need to run "update" between the 2 inserts?
    – StealthRT
    Commented Aug 22, 2012 at 13:11
  • 3
    @StealthRT Yes, just like that - but you must execute the second immediately after the first, or the value of LAST_INSERT_ID() will become invalid. The LAST_INSERT_ID() is connection dependent, so as long as these are executed sequentially on the same connection, you'll get the right value back. If any other inserts happen in between, you'll get the wrong value. Commented Aug 22, 2012 at 13:18
28

you can't use VALUES clause when inserting data using another SELECT query. see 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
);
0
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
)

Not the answer you're looking for? Browse other questions tagged or ask your own question.