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 :

Insert into matable (Chp1, Chp2, Chp3) select distinct


Sujet :

Requêtes MySQL

  1. #1
    Membre du Club
    Homme Profil pro
    Épine dans le pieds
    Inscrit en
    Mai 2004
    Messages
    425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Épine dans le pieds

    Informations forums :
    Inscription : Mai 2004
    Messages : 425
    Points : 55
    Points
    55
    Par défaut Insert into matable (Chp1, Chp2, Chp3) select distinct
    Bonjour,

    J'ai 1 table visits dans laquelle mes visiteurs stockent des infos :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE TABLE `visits` (
      `rec_num` int(11) NOT NULL auto_increment,
      `vis_date` bigint(20) default NULL,
      `rank` varchar(4) default NULL,
      `rank_seniority` int(11) default NULL,
      `licence` varchar(4) default NULL,
      `licence_seniority` int(11) default NULL,
      `employer` varchar(4) default NULL,
      ...
      `cvisits` int(11) NOT NULL default '1',
      `member_id` int(11) NOT NULL,
      `action_ref` int(11) default NULL,
      `company_id` int(11) default NULL,
      `employer_id` int(11) default NULL,
      PRIMARY KEY  USING BTREE (`rec_num`,`member_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=242 DEFAULT CHARSET=utf8
    J'établis des critères de sélection et veux savoir combien de membres correspondent. Jusque là, pas de soucis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT COUNT(DISTINCT member_id) FROM visits WHERE member_id>0
    AND (rank='CDT' OR rank='CEN') AND rank_seniority<5 AND
    (licence='MAUN' OR licence='CEUN' OR licence ='CE15')
    Maintenant imaginons que je veuille ajouter une ligne dans une deuxième table, pour chacun de ces membres sélectionnés :

    Ma table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE `selectobject` (
      `rec_num` int(11) NOT NULL auto_increment,
      `select_date` timestamp NOT NULL default CURRENT_TIMESTAMP,
      `member_id` int(11) NOT NULL,
      `object_ref` int(11) NOT NULL,
      `object_type` int(11) NOT NULL,
      `answer_date` datetime default NULL,
      `report_date` datetime default NULL,
      PRIMARY KEY  USING BTREE (`rec_num`,`object_type`,`object_ref`,`member_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=311 DEFAULT CHARSET=utf8 COMMENT='link betwn members and polls, adds,joboffers...'
    Je connais object_ref, object_type.
    select_date est un timestamp.
    answer_date et report_date restent null :

    J'essaye une première requête qui fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    INSERT INTO selectobject (object_type, object_ref, member_id) SELECT
    $object_type, $object_ref, member_id FROM visits WHERE member_id>0
    AND (rank='CDT' OR rank='CEN') AND rank_seniority<5 AND
    (licence='MAUN' OR licence='CEUN' OR licence ='CE15')
    Par contre, comment ajouter le DISTINCT ? Cette requête ne marche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    INSERT INTO selectobject (object_type, object_ref, member_id) SELECT
    $object_type, $object_ref, DISTINCT member_id FROM visits WHERE
    member_id>0 AND (rank='CDT' OR rank='CEN') AND rank_seniority<5
    AND (licence='MAUN' OR licence='CEUN' OR licence ='CE15')
    Cerise sur le gâteau, chaque membre pouvant saisir plusieurs entrées dans la table visits (par exemple à plusieurs mois d'intervalle), comment ne tenir compte que de la dernière de ces déclarations ?

    En comptage, celle-ci semble ok :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT COUNT(DISTINCT member_id) max(vis_date) FROM visits WHERE
    member_id>0 AND (rank='CDT' OR rank='CEN') AND rank_seniority<5
    AND (licence='MAUN' OR licence='CEUN' OR licence ='CE15')
    Mais en INSERT, cela ne marche plus car j'ai une différence de nombre de champs retournés par ma requête SELECT et remplis par ma requête INSERT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO selectobject (object_type, object_ref, member_id) SELECT
    $object_type, $object_ref, DISTINCT member_id max(vis_date)
    FROM visits WHERE member_id>0 AND (rank='CDT' OR rank='CEN')
    AND rank_seniority<5 AND (licence='MAUN' OR licence='CEUN' OR
    licence ='CE15')
    Une idée ?

    Merci de votre aide !

    Px

  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 : 72
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Saluton,
    Tu as une interprétation erronée de l'action de DISTINCT dans les n_uplets d'un SELECT, il agit sur l'unicité de l'ensemble des colonnes.
    Ce n'est pas comme lorsque tu fais SELECT COUNT (DISTINCT truc), autreColonne, etc...
    Dans ce cas, le comptage n'opère que sur des éléments différents, mais nous sommes dans un autre contexte.
    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 du Club
    Homme Profil pro
    Épine dans le pieds
    Inscrit en
    Mai 2004
    Messages
    425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Épine dans le pieds

    Informations forums :
    Inscription : Mai 2004
    Messages : 425
    Points : 55
    Points
    55
    Par défaut
    Zut j'avais ajouté une réponse mais j'ai eu un gros "ERROR 500" ! (sans doute un problème de requête ?-).

    J'avais lu que DISTINCT s'appliquait à toutes les colonnes remontées par une requête (pardon de mon langage anormalisé), ce qui explique que ma 1ère requête fonctionne.

    Quelles solutions alors pour cette requête ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    INSERT INTO selectobject (object_type, object_ref, member_id) SELECT
    $object_type, $object_ref, DISTINCT member_id FROM visits WHERE
    member_id>0 AND (rank='CDT' OR rank='CEN') AND rank_seniority<5
    AND (licence='MAUN' OR licence='CEUN' OR licence ='CE15')
    Et comment faire pour celle-ci ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    INSERT INTO selectobject (object_type, object_ref, member_id) SELECT
    $object_type, $object_ref, DISTINCT member_id max(vis_date)
    FROM visits WHERE member_id>0 AND (rank='CDT' OR rank='CEN')
    AND rank_seniority<5 AND (licence='MAUN' OR licence='CEUN' OR
    licence ='CE15')
    Une idée, quelqu'un ?

    merci

    Px

  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 : 72
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Tu vas devoir passer par deux requêtes:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    INSERT INTO selectobject ( member_id) 
    SELECT DISTINCT member_id FROM visits 
    WHERE member_id>0 
    AND (rank='CDT' OR rank='CEN') 
    AND rank_seniority<5
    AND (licence='MAUN' OR licence='CEUN' OR licence ='CE15')
    puis
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE selectobject 
    SET object_type=$object_type, object_ref=$object_ref
    WHERE member_id IN (SELECT DISTINCT member_id FROM visits 
    WHERE member_id>0 
    AND (rank='CDT' OR rank='CEN') 
    AND rank_seniority<5
    AND (licence='MAUN' OR licence='CEUN' OR licence ='CE15'))
    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 du Club
    Homme Profil pro
    Épine dans le pieds
    Inscrit en
    Mai 2004
    Messages
    425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Épine dans le pieds

    Informations forums :
    Inscription : Mai 2004
    Messages : 425
    Points : 55
    Points
    55
    Par défaut
    Effectivement c'est une solution. Je n'y avais pas pensé. Merci pour cette réponse.

    Par contre, ça ne résout pas mon dernier problème qui est de sélectionner le membre qu'en fonction de sa dernière déclaration dans ma table visits ?

    Est-ce qu'il existe un concept de tables virtuelles ou temporaire sous Mysql ? Parce que dans ce cas je pourrais d'abord rechercher la dernière déclaration pour chaque membre, stocker ces résultats dans une table temporaire, puis lancer une requête pour créer les enregistrements de la tables selectobject.

    Dans ce cas, d'ailleurs, pas besoin de distinct puisque j'aurais déja fait le tri avec la première requête.

    Px

  6. #6
    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 : 72
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par Perplexe Voir le message
    Est-ce qu'il existe un concept de tables virtuelles ou temporaire sous Mysql ?
    Oui : http://dev.mysql.com/doc/refman/5.0/...ge-engine.html
    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)

  7. #7
    Membre du Club
    Homme Profil pro
    Épine dans le pieds
    Inscrit en
    Mai 2004
    Messages
    425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Épine dans le pieds

    Informations forums :
    Inscription : Mai 2004
    Messages : 425
    Points : 55
    Points
    55
    Par défaut
    Merci pour ce lien.

    J'ai finalement opté pour la solution suggérée : créé une table dans laquelle je stocke, pour chaque membre, les dernière informations saisies.

    Je fais un update sur la ligne correspondant au membre à chaque saisie d'informations nouvelles, donc je garde une seule ligne par membre (l'historique des saisies étant conservé dans la table visits).

    De cette manière, je résous à la fois mon problème de DISTINCT et mon problème de MAX(vis_date).

    Merci pour tout !

    Px

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

Discussions similaires

  1. Insert into avec valeur fixe et select
    Par Isalite dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 15/11/2013, 17h06
  2. Réponses: 2
    Dernier message: 27/01/2011, 16h42
  3. Réponses: 15
    Dernier message: 27/01/2011, 11h00
  4. C8 RS pb clause in(chp1,chp2,chp3)
    Par Ne0zenith dans le forum Cognos
    Réponses: 2
    Dernier message: 17/04/2009, 20h06
  5. Insert Into dans une table avec select
    Par smail25 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 15/12/2006, 13h06

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