web-dev-qa-db-fra.com

Insertion MySQL dans la table avec incrémentation automatique lors de la sélection dans une autre table

J'ai une table avec une clé primaire à incrémentation automatique:

create table rt_table
(
  rtID int PRIMARY KEY AUTO_INCREMENT, 
  rt_user_id BIGINT,               /*user being retweeted*/
  rt_user_name varchar(70),        /*user name of rt_user_id*/
  source_user_id BIGINT,           /*user tweeting rt_user_id*/
  source_user_name varchar(70),    /*user name of source_user_id*/
  Tweet_id BIGINT,                 /*fk to table tweets*/

  FOREIGN KEY (Tweet_id) references tweets(Tweet_id)
);

Je souhaite remplir ce tableau à partir de parties d'un autre tableau:

insert into rt_table 
select rt_user_id, (select user_name from users u where u.user_id = t.rt_user_id),
       source_user_id, (select user_name from users u where u.user_id = t.source_user_id),
       Tweet_id
  from tweets t
 where rt_user_id != -1;

J'obtiens une erreur indiquant que le nombre de colonnes ne correspond pas, ce qui est dû à la clé primaire (qui est une valeur auto-incrémentée et n'a donc pas besoin d'être définie). Comment puis-je contourner cela?

16
CodeKingPlusPlus

Vous devez répertorier explicitement les colonnes dans l'instruction insert:

insert into rt_table (rt_user_id, rt_user_name, source_user_id, source_user_name, Tweet_id)
select rt_user_id, (select user_name from users u where u.user_id = t.rt_user_id),
       source_user_id, (select user_name from users u where u.user_id = t.source_user_id),
       Tweet_id
  from tweets t
 where rt_user_id != -1;

En outre, je pense qu'il est préférable d'utiliser des jointures explicites plutôt que des sélections imbriquées:

insert into rt_table (rt_user_id, rt_user_name, source_user_id, source_user_name, Tweet_id)
    select t.rt_user_id, u.user_name, t.source_user_id, su.user_name, t.Tweet_id
    from tweets t left outer join
         users u
         on t.rt_user_id = u.user_id left outer join
         users su
         on t.source_user_id = su.user_id
    where rt_user_id != -1;

Cela aide souvent (mais pas toujours) l'optimiseur à trouver le meilleur plan de requête.

27
Gordon Linoff

Vous définissez simplement la clé primaire sur NULL pendant l'insertion.

INSERT INTO rt_table 
SELECT 
  NULL,
  rt_user_id,
  (SELECT 
    user_name 
  FROM
    users u 
  WHERE u.user_id = t.rt_user_id),
  source_user_id,
  (SELECT 
    user_name 
  FROM
    users u 
  WHERE u.user_id = t.source_user_id),
  Tweet_id 
FROM
  tweets t 
WHERE rt_user_id != - 1 ;
23
Styphon