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 :

Requête tous les bars avec une seule table


Sujet :

Langage SQL

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Février 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2015
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Requête tous les bars avec une seule table
    Bonjour,
    je m'entraine à faire de requête et je suis tombé sur un problème sur le net (sur le le site de l'enst) que je 'arrive pas à résoudre même avec la solution.

    Voila. J'ai une table fréquente(bar,buveur) et il faut trouver les buveurs qui fréquentent tous les bars.

    Je peux comprendre qu'il faut faire une autojonction sur la table, mais je ne vois pas comme on fait.
    sinon je pensais résoudre le problème avec un not(les buveurs qui ne fréquentent pas un bar)

    si une ame charitable pouvait m'éclairer, merci d'avance.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 895
    Points : 53 123
    Points
    53 123
    Billets dans le blog
    6
    Par défaut
    "tous les..." c'est le signe générique d'une division relationnelle; À me lire : http://sqlpro.developpez.com/cours/divrelationnelle/

    A +

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Février 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2015
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci pour ton cours SQL. Il est au top. Tout est bien expliqué et comprend très bien

    La solution qu'il donnait était celle la :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT Distinct Buveur 
    FROM Fréquenter 
    WHERE Buveur NOT IN
    (SELECT F1.Buveur 
    FROM Fréquenter F1, Fréquenter F2 
    WHERE F1.Buveur NOT IN
    (SELECT Buveur 
    FROM Fréquenter 
    WHERE Bar=F2.Bar)
    );
    Je ne comprend pas le dernier sélect et le F2. Si tu pouvais m'eclairer.

    au niveau rapidité d'exécution est elle moins bien que de passer par des group by et des having??

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 895
    Points : 53 123
    Points
    53 123
    Billets dans le blog
    6
    Par défaut
    C'est encore une de ses horribles jointures dans la clause WHERE !!!... Si c'est votre enseignant qui vous a indiqué que les jointures se font comme ceci c'est un vieux con ! (poussez le à la retraite, ça fera de la place pour des gens compétents !) En effet, les jointures se font à l'aide de l'opérateur JOIN depuis le norme SQL 2 de 1992 !!! Bref, il a 23 ans de retard....

    Pour couronner le tout, cette requête est tout à fait tordue puisqu'elle fait appel à 4 fois la table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT Distinct Buveur
    FROM   Fréquenter
    WHERE  Buveur NOT IN (SELECT F1.Buveur
                          FROM   Fréquenter AS F1 , Fréquenter AS F2
                          WHERE  F1.Buveur NOT IN (SELECT Buveur
                                                   FROM   Fréquenter
                                                   WHERE  Bar=F2.Bar));
    Sous forme NOT EXISTS, bien plus rapide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT Distinct Buveur
    FROM   Fréquenter AS F0
    WHERE  NOT EXISTS (SELECT F1.Buveur
                       FROM   Fréquenter AS F1
                       WHERE  NOT EXISTS (SELECT Buveur
                                          FROM   Fréquenter AS F2
                                          WHERE  F1.Bar = F2.Bar
                                            AND  F0.Buveur = F2.Buveur));
    Il n'y a qu'à comparer les plans de requête.....

    A +

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    J'ai une table fréquente(bar,buveur) et il faut trouver les buveurs qui fréquentent tous les bars.
    Si vous n'avez que cette table, alors on suppose que tous les bars sont présents dans cette table et qu'ils sont donc fréquentés tous au moins une fois. Mais votre table ressemble à une table associative dans laquelle la colonne bar ferait référence à la table des bars et la colonne buveur fait référence à la table des buveurs.

    Restons sur l'hypothèse que tous les bars sont dans la table fréquente...

    Combien y a t-il de bars ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT COUNT(DISTINCT bar) AS nb_bars
    FROM frequente
    Combien de bars différents fréquente chaque buveur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT buveur, COUNT(DISTINCT bar) AS nb_bar_par_buveur
    FROM frequente
    GROUP BY buveur
    Quels sont les buveurs qui fréquentent tous les bars ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT buveur
    FROM frequente
    GROUP BY buveur
    HAVING COUNT(DISTINCT bar) = 
    (
    	SELECT COUNT(DISTINCT bar)
    	FROM frequente
    )

Discussions similaires

  1. [AC-2007] Champ calculé comme valeur dans une requête analyses croisées avec une seule table
    Par The old fool dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 11/10/2014, 10h15
  2. Réponses: 2
    Dernier message: 29/03/2014, 21h55
  3. Réponses: 8
    Dernier message: 06/07/2008, 11h44
  4. Merge mais avec une seule table : possible?
    Par kissskoool dans le forum SQL
    Réponses: 10
    Dernier message: 10/03/2008, 13h53
  5. [FN]Faire 1 BD avec une seule table ou normaliser ?
    Par borndead dans le forum Schéma
    Réponses: 7
    Dernier message: 12/06/2007, 15h26

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