IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

UPDATE dans 2 Tables avec un COUNT


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Points : 121
    Points
    121
    Par défaut UPDATE dans 2 Tables avec un COUNT
    -- Voici le contexte minimal

    CREATE TABLE `CLIENT` (
    `ID_CLIENT` int(11) NOT NULL,
    `POINT_FIDELITE` int(11),
    PRIMARY KEY (`ID_CLIENT`)
    );

    CREATE TABLE `ACHAT` (
    `ID_ACHAT` int(11) NOT NULL,
    `ID_CLIENT` int(11) NOT NULL,
    `ACHAT_VALIDE` datetime,
    PRIMARY KEY (`ID_ACHAT`)
    );


    -- Initialisation `CLIENT`:
    INSERT INTO `CLIENT` (`ID_CLIENT`, `POINT_FIDELITE`) VALUES
    (1, 0),(2, 0);

    -- Initialisation `ACHAT`:
    INSERT INTO `ACHAT` (`ID_ACHAT` ,`ID_CLIENT` ,`ACHAT_VALIDE` )
    VALUES ('1', '1', NULL), ('2', '1', NULL),
    ('3', '2', NULL ), ('4', '2', NULL ), ('5', '2', NULL);


    -- Je souhaite avec un minimum de requete (une si possible):
    -- assigner NOW() à tous les `ACHAT_VALIDE` sans date (IS NULL)
    -- ajouter à `POINT_FIDELITE` le Nb des `ACHAT_VALIDE` qui seront assigné à NOW()


    -- Je bloque, voici la requete qui ne marche pas (erreur de syntaxe):

    UPDATE `CLIENT`, `ACHAT` SET `ACHAT_VALIDE`=NOW(), `POINT_FIDELITE`=`POINT_FIDELITE`+(
    -- Que mettre ici pour compter le nombre d'achat qui vont être validé à NOW() ?
    -- j'ai une erreur de syntaxe avec ceci :
    -- SELECT COUNT(*) WHERE
    --`CLIENT`.`ID_CLIENT`=`ACHAT`.`ID_CLIENT` AND
    --`ACHAT`.`ACHAT_VALIDE` IS NULL

    )
    WHERE
    `CLIENT`.`ID_CLIENT`=`ACHAT`.`ID_CLIENT` AND
    `ACHAT`.`ACHAT_VALIDE` IS NULL

  2. #2
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Points : 121
    Points
    121
    Par défaut
    Précision : MySQL 5.0.45
    Je viens de corriger une coquille dans le POST précédent :

    `ACHAT`.`ACHAT_VALIDE` (et non `CLIENT`.`ACHAT_VALIDE`)

  3. #3
    Membre confirmé Avatar de TryExceptEnd
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 501
    Points : 576
    Points
    576
    Par défaut
    Il ne manque pas un "FROM" au "SELECT" de la sous requete ?

  4. #4
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par TryExceptEnd Voir le message
    Il ne manque pas un "FROM" au "SELECT" de la sous requete ?
    Non pas autorisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    UPDATE `CLIENT` ,
    `ACHAT` SET `ACHAT_VALIDE` = NOW( ) ,
    `POINT_FIDELITE` = `POINT_FIDELITE` + ( 
    SELECT COUNT( * ) 
    FROM `CLIENT` , `ACHAT` 
    WHERE `CLIENT`.`ID_CLIENT` = `ACHAT`.`ID_CLIENT` 
    AND `ACHAT`.`ACHAT_VALIDE` IS NULL 
    ) 
    WHERE `CLIENT`.`ID_CLIENT` = `ACHAT`.`ID_CLIENT` 
    AND `ACHAT`.`ACHAT_VALIDE` IS NULL 
    
    MySQL a répondu: 
    
    #1093 - You can't specify target table 'CLIENT' for update in FROM clause 

  5. #5
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Points : 121
    Points
    121
    Par défaut
    J'ai une incertitude quand à l'ordre de modification de la requete précédente (si elle marchait..). En effet, il faut être sur de l'état exact de`ACHAT_VALIDE`puisque l'on assigne `POINT_FIDELITE` en fonction de `ACHAT_VALIDE` dans une seule et même requete. Pour lever l'incertitude j'ai fait l'opération en 2 update distinct :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT NOW() INTO @maintenant;
    
    UPDATE `ACHAT` SET `ACHAT_VALIDE`=@maintenant
    WHERE `ACHAT`.`ACHAT_VALIDE` IS NULL;
    
    UPDATE `CLIENT`, `ACHAT` SET  `POINT_FIDELITE`=`POINT_FIDELITE`+(
     SELECT COUNT(*) WHERE `CLIENT`.`ID_CLIENT`=`ACHAT`.`ID_CLIENT` AND 
    `ACHAT`.`ACHAT_VALIDE`= @maintenant
    ) WHERE 
    `CLIENT`.`ID_CLIENT`=`ACHAT`.`ID_CLIENT` AND 
    `ACHAT`.`ACHAT_VALIDE`= @maintenant ;
    Le premier update (élémentaire) passe bien, mais toujours pas le second, j'arrive pas a faire passer la pilule (en bleu dans le code) : retourner le nombre d'achat validé pour chaque client... (et c'est pas le FROM qui manque)

  6. #6
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Points : 121
    Points
    121
    Par défaut
    Ca me dérangerais vraiment de devoir faire le traitement coté applicatif.. pas très propre, mais peut être que SQL permet en théorie ce type de requete, mais pas MySQL 5.1.. ?

  7. #7
    Membre régulier
    Inscrit en
    Mai 2007
    Messages
    183
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 183
    Points : 121
    Points
    121
    Par défaut
    Bon bas la réponse est dans : http://dev.mysql.com/doc/refman/5.0/...ry-errors.html

    Cette erreur survient dans des cas comme celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
    Il est valide d'utiliser une sous-requête lors d'une affectation dans une commande UPDATE, car les sous-requêtes sont valides avec les commandes UPDATE et DELETE, tout comme dans les commandes SELECT. Cependant, vous ne pouvez pas les utiliser sur la même table, qui est ici t1, car cette table est alors la cible de la clause FROM et de la commande UPDATE.
    Donc la solution qui marche est en 2 parties :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT NOW() INTO @maintenant;
     
    UPDATE `ACHAT` SET `ACHAT_VALIDE`=@maintenant
    WHERE `ACHAT`.`ACHAT_VALIDE` IS NULL;
     
    UPDATE `CLIENT`, `ACHAT` SET  `POINT_FIDELITE`=`POINT_FIDELITE`+(
     SELECT COUNT(*) FROM `ACHAT` WHERE `CLIENT`.`ID_CLIENT`=`ACHAT`.`ID_CLIENT` AND 
    `ACHAT`.`ACHAT_VALIDE`= @maintenant
    ) WHERE 
    `CLIENT`.`ID_CLIENT`=`ACHAT`.`ID_CLIENT` AND 
    `ACHAT`.`ACHAT_VALIDE`= @maintenant ;
    Avant de mettre "Résolu", je laisse le post ouvert encore une heure pour d'éventuels commentaires avisé des Modérateurs.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/10/2013, 16h45
  2. [MySQL] Ajouter des données dans une table avec la cmd update
    Par pierrot10 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 25/09/2007, 19h54
  3. [MySQL] Insertion de code HTML dans une table, avec UPDATE
    Par Daedalus31 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 05/02/2007, 12h19
  4. [Debutant]Suppression dans des tables avec contraintes
    Par Roming22 dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 26/10/2004, 17h23
  5. UPDATE d'une table avec test d'un champ d'une autre table
    Par delphim dans le forum Langage SQL
    Réponses: 2
    Dernier message: 03/05/2004, 12h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo