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

Requêtes MySQL Discussion :

UPDATE et INNER JOIN


Sujet :

Requêtes MySQL

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 100
    Par défaut UPDATE et INNER JOIN
    Bonjour,

    Afin d'éviter de lancer trop de requêtes et de dépasser la limite des 30 secondes pour un script php, je dois optimiser une série d'INSERT et de UPDATE grâce à INNER JOIN.

    J'utilise avec succès depuis pas mal de temps les INNER JOIN pour des requête SELECT, mais je ne m'étais jamais essayé aux INSERT et aux UPDATE et je dois avouer que là, je suis un peu perdu.

    J'ai ainsi créé deux requêtes : une SELECT et une UPDATE. Ces deux requêtes ont exactement les mêmes WHERE et INNER JOIN. Pourtant, la requête SELECT trouve une seule valeur dans ma base répondant aux critères (ce qui est la bonne réponse), alors que la UPDATE en trouve deux.

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT note.id_site
    FROM note
    INNER JOIN site
    INNER JOIN banniere728x90
    INNER JOIN credit
    WHERE
    site.id_membre!=24 AND site.langue="fr" AND site.actif="1"
    AND banniere728x90.id_site=site.id_site
    AND credit.id_membre=site.id_membre AND credit.credit>0
    AND note.id_site_out=site.id_site AND note.id_site_in=16 AND note.format="728x90"

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    UPDATE note
    INNER JOIN site
    INNER JOIN banniere728x90
    INNER JOIN credit
    SET note.note_site = note.note_site + 1
    WHERE
    site.id_membre!=24 AND site.langue="fr" AND site.actif="1"
    AND banniere728x90.id_site=site.id_site
    AND credit.id_membre=site.id_membre AND credit.credit>0
    AND note.id_site_out=site.id_site AND note.id_site_in=16 AND note.format="728x90"

    Le paramètre qui ne semble pas fonctionner dans la deuxième requête est la correspondance entre "note.id_site_out=site.id_site" et "banniere728x90.id_site=site.id_site" car le UPDATE modifie une entrée qui existe dans les tables "note" et "site" mais pas dans "banniere728x90".

    Savez-vous où je me suis trompé ?

    Merci d'avance pour vos réponses, ou au moins d'avoir lu jusqu'ici.

  2. #2
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Saluton,
    Tout d'abord merci, car tu viens de m'apprendre quelque chose .
    INNER JOIN et , (virgule) sont sémantiquement équivalents. Les deux opèrent une jointure totale sur les tables utilisées. Normalement, vous spécifiez les conditions de jointure dans la clause WHERE.
    Un des intérêts des syntaxes avec JOIN, c'est de séparer les conditions de jointures, que l'on décline derrière l'opérateur ON, des conditions de filtrage que l'on rattache aux clauses WHERE et/ou HAVING. Ceci afin d'améliorer la lisibilité des requêtes et, par tant, d'en faciliter la maintenance.
    D'autre part, on a l'habitude de renommer (avec AS facultatif) les tables pour réduire la saisie.
    Par exemple ta requête se présenterait comme ci-dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT n.id_site
    FROM note AS n
    INNER JOIN site AS s ON n.id_site_out=s.id_site
    INNER JOIN banniere728x90 AS b ON b.id_site=s.id_site
    INNER JOIN credit AS c ON c.id_membre=s.id_membre
    WHERE s.id_membre!=24
    AND s.langue="fr"
    AND s.actif="1"
    AND c.credit>0
    AND n.id_site_in=16
    AND n.format="728x90"
    Ceci dit, ton diagnostic m'apparaît erroné dans la mesure où la colonne incrémentée par le SET (note.note_site) n'intervient en aucune manière dans les clauses de jointures.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 100
    Par défaut
    Ceci dit, ton diagnostic m'apparaît erroné dans la mesure où la colonne incrémentée par le SET (note.note_site) n'intervient en aucune manière dans les clauses de jointures.
    L'incrémentation n'est pas ce qui me pose problème, loin de là. Le problème survenait sur la sélection des enregistrements à modifier.

    En tout cas, je te remercie pour ces explications. En séparant les critères de sélection, le problème s'est réglé tout seul. Je n'ai pas trouvé d'explication, mais bon, l'important, c'est que ça marche !

    Par contre, je suis maintenant confronté à un autre problème qui prouve à quel point je connais mal les jointures.

    La requête UPDATE suivante fonctionne désormais correctement :

    UPDATE note AS n
    INNER JOIN site AS s ON n.id_site_out=s.id_site
    INNER JOIN banniere728x90 AS b ON b.id_site=s.id_site
    INNER JOIN credit AS c ON c.id_membre=s.id_membre
    SET n.note_ste = n.note_site + 1
    WHERE s.id_membre!=24
    AND s.langue="fr"
    AND s.actif="1"
    AND c.credit>0
    AND n.id_site_in=16
    AND n.format="728x90"
    Mon problème se pose désormais sur la requête INSERT qui fonctionne de paire avec l'UPDATE.

    Le code précédent est utilisé pour gérer l'affichage de lien externe sur un site donné. Afin d'optimiser l'affichage, une note est attribuée à chaque lien et est enregistrée dans la table "note".
    Cette table "note" est composée de quatre champs :
    - id_site_in : l'id du site sur lequel est affiché le lien
    - id_site_out : l'id du lien
    - format : le format du lien (728x90, 468x60...)
    - note : le note du lien

    Chaque note est unique. Ainsi, il n'existe qu'une seule note par lien sur un même site.

    Dans l'UPDATE qui se trouve ci-dessus, je modifie la note des liens correspondant aux critères de recherche. Mais quand c'est la première fois qu'une note est attribuée, il faut alors créé un nouvel enregistrement et cela peut amener le script à créer beaucoup d'enregistrement en une seule. Je suis donc obligé de faire une jointure.

    Et c'est là que ça bloque...

    Si je lance la requête suivante, cela devrait me créer un enregistrement à chaque fois qu'une relation correspond aux critères :
    INSERT INTO note AS n
    INNER JOIN site AS s ON n.id_site_out=s.id_site
    INNER JOIN banniere728x90 AS b ON b.id_site=s.id_site
    INNER JOIN credit AS c ON c.id_membre=s.id_membre
    ("id_site_in", "id_site_out", "format", "note") VALUES ("16", s.id_site, "728x90", 100)
    WHERE s.id_membre!=24
    AND s.langue="fr"
    AND s.actif="1"
    AND c.credit>0
    AND n.id_site_in=16
    AND n.format="728x90"
    C'est pas mal, mais ce que je veux faire, cela créé une note, même si il en existe déjà une. Or, ce que je veux faire, c'est créer un enregistrement à chaque fois qu'une relation correspond aux critères et qu'une note n'existe pas.
    Mais je n'arrive pas à faire cela. Savez-vous comment faire ?

    Merci d'avance à celui qui m'aidera.

    Korbn

  4. #4
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    En coup de vent car je suis charrette ce matin en raison de la journée de grève qui s'annonce.
    Je me demande si tu ne devrais pas te tourner vers une requête INSERT....ON DUPLICATE KEY UPDATE.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 100
    Par défaut
    Effectivement, le ON DUPLICATE KEY UPDATE est très pratique dans ce cas-là.

    Et en allant faire de plus ample recherche sur ON DUPLICATE KEY UPDATE, j'ai trouvé une réponse partielle à ma question et ai appris un point très important : une clef primaire peut inclure plusieurs champs, ce qui est parfait dans le cas présent puisque ce sont les couples (ou plutôt les trios) "id_site_in" - "id_site_in" - "format" qui sont uniques.

    Merci beaucoup !

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

Discussions similaires

  1. REQUETE UPDATE avec INNER JOIN
    Par vero81 dans le forum SQL
    Réponses: 1
    Dernier message: 07/08/2009, 16h45
  2. Problème avec UPDATE et INNER JOIN
    Par korbn dans le forum Requêtes
    Réponses: 2
    Dernier message: 25/05/2009, 20h52
  3. [MySQL] UPDATE et INNER JOIN
    Par korbn dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 25/05/2009, 14h27
  4. probleme update et inner join
    Par makaphrodite dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/04/2009, 11h44
  5. UPDATE avec INNER JOIN
    Par steelidol dans le forum MS SQL Server
    Réponses: 11
    Dernier message: 03/03/2006, 23h56

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