Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/02/2011, 22h14   #1
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
Par défaut Sac à dos Avec et sans

salut tout le monde,

J'ai un petit problème ...
j'ai une table `sac` avec dedans 2 collones `contenu_id` et `sac_id`

je voudrai récupérer les identifiants des sacs contenant 1 et 2 et pas 3

pour la première partie c'est assez simple :
Code :
1
2
3
4
SELECT *,count(`contenu_id`) FROM `sac`
WHERE `contenu_id` IN (1,2)
GROUP BY `sac_id`
HAVING count(`contenu_id`) = 2
pour la seconde partie c un peu plus dur ..
Code :
1
2
3
4
5
SELECT *,count(`contenu_id`) FROM `sac`
WHERE `contenu_id` IN (1,2)
AND `contenu_id` NOT IN (3)
GROUP BY `sac_id`
HAVING count(`contenu_id`) = 2
avez vous une idée pour m'aider ?
il faudrait que la requète ne soit pas trop longe à exécuter (table assez chargée)

Merci d'avance.
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/02/2011, 23h13   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Bonjour,

Vous pourriez passer par le prédicat not exists pour faire votre test de non existance du contenu 3 sur vos sac.

Sinon, si votre sgbd le supporte une jointure de type except.
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/02/2011, 23h17   #3
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Apparemment, tu es sous MySQL, ce qui exclut EXCEPT et MINUS.

On pourrait le faire avec un NOT EXISTS, mais ça veut dire une sous-requête corrélée, et sous MySQL ça veut des performances catastrophiques. Du coup, il reste le NOT IN...
Code :
1
2
3
4
5
6
7
 
SELECT *, count(`contenu_id`) 
FROM `sac`
WHERE `contenu_id` IN (1,2)
  AND sac_id NOT IN (SELECT sac_id WHERE contenu_id = 3)
GROUP BY `sac_id`
HAVING count(`contenu_id`) = 2
... ou alors l'équivalent avec une jointure (devrait être plus efficace, mais à tester) :

Code :
1
2
3
4
5
6
7
8
SELECT *, count(`contenu_id`) 
FROM `sac`
  LEFT JOIN (SELECT sac_id WHERE contenu_id = 3) S2
    ON sac.sac_id = S2.sac_id
WHERE `contenu_id` IN (1,2)
  AND S2.sac_id IS NULL
GROUP BY `sac_id`
HAVING count(`contenu_id`) = 2
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/02/2011, 23h54   #4
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
Il n'y a plus qu'a tester les deux méthodes,

je vous tiens au courrant
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 00h38   #5
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
Alors,

les deux méthodes fonctionnent, niveau rapidité, je ferai les tests plus tard.

juste pour vérification,
si je remplace le : SELECT sac_id WHERE contenu_id = 3
par SELECT sac_id WHERE contenu_id IN (3,4,..)
est-il préférable d'ajouter en plus un group by ?

Merci d'avance.
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 00h41   #6
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Non, quelle drôle d'idée !

Le GROUP BY est utile avec des fonctions d'agrégation comme SUM ou COUNT placées dans le SELECT ou le HAVING, c'est tout.
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 00h46   #7
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
la table étant grande, et le nombre de résultats répondant à la requète "SELECT sac_id WHERE contenu_id IN (3,4,..)" étant très important, cela ne ralentira-t-il pas la requète globale ?

pour : SELECT sac_id WHERE contenu_id IN (3,4,..) GROUP BY sac_id
(valeurs très approximatives)
nombre de résultats sans group by = (nombre de résultats avec group by)*1000

l'idée du select entre parenthèse est bien :
- il va exécuter la requète entre parenthèses en premier
- avec les résultats de la 1eère requète, il va construire la seconde puis l'exécuter
?
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 00h51   #8
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Citation:
Envoyé par rebel29270 Voir le message
la table étant grande, et le nombre de résultats répondant à la requète "SELECT sac_id WHERE contenu_id IN (3,4,..)" étant très important, cela ne ralentira-t-il pas la requète globale ?
ah, je comprends, mais dans ce cas c'est un DISTINCT que tu dois tester, pas un GROUP BY.
Citation:
pour : SELECT sac_id WHERE contenu_id IN (3,4,..) GROUP BY contenu_id
(valeurs très approximatives)
nombre de résultats sans group by = (nombre de résultats avec group by)*1000

l'idée du select entre parenthèse est bien :
- il va exécuter la requète entre parenthèses en premier
- avec les résultats de la 1eère requète, il va construire la seconde puis l'exécuter
?
En l'occurence oui, parce que MySQL implémente les sous-requêtes du FROM en créant une table temporaire. Du coup tu as raison, le DISTINCT devrait améliorer les perfs.

Mais de manière générale, il ne faut pas confondre le raisonnement logique pour produire le résultat et ce que fera vraiment l'optimiseur du SGBD. Je pourrais donc te répondre que c'est effectivement ce qui va se passer, mais que ce n'est pas "l'idée", parce que l'idée est juste de décrire le résultat qu'on veut obtenir et pas le processus d'obtention.
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 00h57   #9
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
On doit pouvoir économiser jointure et sous-requête en filoutant un peu :
Code :
1
2
3
4
5
6
  SELECT sac_id
    FROM sac
   WHERE contenu_id IN (1, 2, 3)
GROUP BY sac_id
  HAVING count(DISTINCT contenu_id) = 2
     AND max(contenu_id) < 3
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 00h59   #10
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Citation:
Envoyé par Waldar Voir le message
On doit pouvoir économiser jointure et sous-requête en filoutant un peu :
Joli !
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 01h13   #11
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
Citation:
Envoyé par Waldar Voir le message
On doit pouvoir économiser jointure et sous-requête en filoutant un peu :
J'y ai déjà pensé mais avec ta requête on obtiens aussi les résultats des sacs contenant (1 et 3) et ceux contenant (2 et 3)
hors justement, je ne veux pas 3...
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 01h15   #12
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Pas du tout, ces lignes-là seront éliminées par le HAVING sur max(contenu_id) < 3.
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 01h18   #13
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
ah oui en effet, mais en fait les valeurs 1, 2 et 3 sont arbitraires,

je pourrait vouloir les sacs avec les objets 1, 3, 5 et 7 et sans le 2, 6 et 71...
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 01h18   #14
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Dans ce cas, tu ne peux effectivement plus filouter
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 01h23   #15
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
Dernières question :
- Est-ce que l'ordre des WHERE machin=truc AND hop=hop2 a une importance ?
- Je sais par expérience (peut-être mauvaise) que les JOINs ont du mal à passer sur les clusters Mysql, la solution que tu m'as donné (Antoun) avec le JOIN serat-elle plus longue dans se cas ? (utilisation d'un cluster)
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2011, 01h29   #16
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
Aucune importance pour la première question, aucune idée pour la seconde.
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/02/2011, 01h31   #17
Candidat au titre de Membre du Club
 
Inscription : mai 2005
Messages : 35
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 35
Points : 10
Points : 10
ok merci pour toutes ces infos !
Demain je poste le résultat de mes tests..

bonne fin de soirée.
rebel29270 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h43.


 
 
 
 
Partenaires

Hébergement Web