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

SQL Procédural MySQL Discussion :

Probleme syntaxe pour intersection


Sujet :

SQL Procédural MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    145
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Juillet 2006
    Messages : 145
    Par défaut Probleme syntaxe pour intersection
    Voilà le problème :

    Soit une table avec des id_user et des id_lieu

    id_user | id_lieu
    1 | 1
    1 | 2
    2 | 1
    2 | 2
    2 | 3
    3 | 1
    4 | 1
    4 | 3

    Je veut tout les Id_user qui fréquente a la fois les Id_lieu '1' et '2'

    Je me doute qu'il faut faire un intersection chose que je sais faire en SQL avec INTERSECT mais malheureusement c'est pas dispo en MySQL donc je me suis rabattu sur une syntaxe avec IN mais impossible de trouvé la bonne syntaxe.

    Une idée ?

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select id_user
    from ta_table
    where id_lieu = 1 and id_user in (
      select id_user
      from ta_table
      where id_lieu = 2);
    autre possibilité, avec une jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select T1.id_user
    from ta_table T1
      inner join (  
    	  select id_user
        from ta_table
        where id_lieu = 2) as T2
    		on T1.id_user = T2.id_user
    where id_lieu = 1 ;
    Dans les deux cas, il faut des sous-requêtes, donc au moins la version 4.1.

  3. #3
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Par défaut
    salut,

    je ne sais pas au niveau performance par rapport aux requetes d'Antoun, mais je ferais quelque chose dans ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select id_user from tatable 
    where id_lieu in (1,2) group by id_user 
    having count(distinct(id_lieu))=2

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    Citation Envoyé par Cybher
    salut,

    je ne sais pas au niveau performance par rapport aux requetes d'Antoun, mais je ferais quelque chose dans ce genre : (...)
    Pour les perfs, je ne sais pas trop, mais ça a l'avantage d'être compatible avec les versions 4.0 et antérieures !

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 9
    Par défaut Autre solution, plus rapide avec des listes importantes
    La solution proposée marche bien, mais sa réalisation peut prendre des plombes .

    Mettons que tu aies 2 listes de personnes: list_A and list_B. Tu veux savoir quelles sont les personnes qui sont dans A et pas dans B. D'un point de vue ensembliste, tu cherches à faire "A moins B".

    Solution facile, mais qui prend du temps:

    select person from list_A where person not in (select person from list_B);

    Dans mon cas, 2 listes de quelques milliers de lignes suffisent à mettre mon serveur 1GB à genoux pendant qqes minutes.


    Le temps de calcul est divisé par 1000 en utilisant l'algorithme suivant:

    1/ crée une table temporaire où tu dumpes les 2 listes
    2/ utilise les fonctions "group" de mysql pour séparer les éléments de l'intersection des éléments hors-intersection

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    create temporary table dump (person varchar(30), list_source char); /* crée la table temporaire*/
    insert into dump select person, 'A' from list_A; /* dump les éléments de list_A dans la table et marque les par la lettre "A"*/
    insert into dump select person, 'B' from list_B; /* dump les éléments de list_B dans la table et marque les par la lettre "B"*/

    -> "A moins B":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select person 
    from (select * from dump group by person having count(*)='1') as T  /* Prends les éléments qui ne sont PAS dans l'intersection ( count='1' ) */
    where list_source='A'; /* Prends uniquement les éléments marqués "A" */

    -> "B moins A":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select person 
    from (select * from dump group by person having count(*)='1') as T  /* Prends les éléments qui ne sont PAS dans l'intersection ( count='1' ) */
    where list_source='B'; /* Prends uniquement les éléments marqués "B" */
    -> "intersection de A et B"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select person from dump group by person having count(*)='2';
    Voilà, ... en attendant que MySQL intégre les opérateurs ensemblistes.

    Bon courage!

    Sibawe

  6. #6
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 288
    Par défaut
    En fait, le problème vient du IN qui est super mal optimisé... Il doit être possible de faire qqch avec EXISTS qui soit efficace.

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

Discussions similaires

  1. [OL-2007] probleme de syntaxe pour afficher une fenetre outlook prédéfini
    Par joetitia dans le forum VBA Outlook
    Réponses: 0
    Dernier message: 11/01/2011, 02h19
  2. problem de syntaxe pour excel sql
    Par DIDIDIDA dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 22/01/2008, 19h26
  3. problem de syntaxe pour excel sql vba
    Par DIDIDIDA dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 21/01/2008, 14h32
  4. [debutant] probleme de syntaxe pour un serveur
    Par Moufette91 dans le forum Autres
    Réponses: 2
    Dernier message: 16/05/2007, 12h00
  5. [SQL] probleme de syntaxe pour afficher une photo en php
    Par carmen256 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 11/04/2006, 21h48

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