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 06/05/2011, 12h27   #1
Invité de passage
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 2
Points : 2
Par défaut Regroupement avec une contrainte

Bonjour,

Je voudrais faire une requête sur trois tables. J'ai une table de repère squi contient un ou plusieurs articles, une table d'articles qui contient une ou plusieurs matières premières et une table de matières.

Je souhaiterai obtenir pour chaque repère les matières utilisées.

Je peux donc les obtenir facilement obtenir :
Code :
1
2
3
4
5
6
7
8
9
Rep1    Art1    MP1
Rep1    Art1    MP2
Rep1    Art1    MP3
Rep1    Art1    MP4
Rep1    Art2    MP1
Rep1    Art2    MP2
Rep1    Art2    MP3
Rep2    Art1    MP1
...
Mais maintenant, je voudrasi pour chaque repère, seulement les matières communes aux articles si il y en a plusieurs.

Résultat que je souhaiterais :
Code :
1
2
3
4
5
Rep1    MP1
Rep1    MP2
Rep1    MP3
Rep2    MP1
...
J'ai regardé avec intersect ou les group by mais je ne trouve pas mon bonheur. Je bloque vraiment et j'espère que quelqu'un pourra me venir en aide.

Merci

Grinvald
Grinvald est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 13h20   #2
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
bonjour

pourrais tu, au moins, indiquer la requête qui a permis d'obtenir les résultats 1
(et éventuellement la structure simplifiée des tables)

et la base de données utilisée
dehorter olivier est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 14h51   #3
Invité de passage
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 2
Points : 2
J'utilise une base SQL Server et voila la structure simplifié.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Repere
--------------
ID_Repere
Nom
 
 
Repere_Ligne
--------------
ID_Repere
ID_Article
 
 
Article
--------------
ID_Article
Nom
 
 
Article_Ligne
--------------
ID_Article
ID_MP
 
 
MP
--------------
ID_MP
Nom
Et voila la requète utilisé :
Code :
1
2
3
4
5
6
SELECT Repere.Nom, Article.Nom, MP.Nom
FROM Repere
JOIN Repere_Ligne ON Repere.ID_Repere = Repere_Ligne.ID_Repere
JOIN Article ON Article.ID_Article = Repere_Ligne.ID_Article
JOIN Article_Ligne ON Article.ID_Repere = Article_Ligne.ID_Repere
JOIN MP ON MP.ID_MP = Article_Ligne.ID_MP
Désolé pour le manque d'info et merci pour ton aide.
Grinvald est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 16h04   #4
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
re

en utilisant "simplement ta requete" et en faisant une sous-requete

Code :
1
2
3
4
5
6
7
8
9
10
11
12
      SELECT Selection.Nom,
             Selection.Mp
        FROM (SELECT Repere.Nom,
                     Article.Nom AS Art,
                     Mp.Nom
                FROM Repere
                  JOIN Repere_ligne ON Repere.Id_repere = Repere_ligne.Id_repere
                  JOIN Article ON Article.Id_article = Repere_ligne.Id_article
                  JOIN Article_ligne ON Article.Id_repere = Article_ligne.Id_repere
                  JOIN Mp ON Mp.Id_mp = Article_ligne.Id_mp) Selection
      GROUP BY Selection.Nom, Selection.Mp
      HAVING Count(*) > 1

reponse rapide, qui je suis sur pourrait etre optimisee (quelque chose ne me plait pas la dedans )
dehorter olivier est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 16h23   #5
Invité de passage
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 2
Points : 2
Ta requête marche mais elle ne répond pas vraiment à mon besoin.

La requête ne garde que les valeurs en double. Ça marcherait nickel si j'avais toujours 2 articles rattachés, mais il se peut qu'il y en ait 1, 2, 3 ...
C'est tout de suite plus chaud.
Grinvald est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 16h35   #6
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
je ne comprends pas !

elle conserve pour tous les couples (nom, mp) pour lesquelles art se retrouve 2 fois et plus "HAVING Count(*) > 1"

ce n'est pas ce tu voulais ?
dehorter olivier est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 17h01   #7
Membre émérite
 
Avatar de Drizzt [Drone38]
 
Homme
Inscription : mai 2004
Messages : 739
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : mai 2004
Messages : 739
Points : 979
Points : 979
Tu peux utiliser les fonctions analytiques.
A priori (cf SQL de A à Z) sur SQL Server tu as la fonction COUNT avec fenêtrage de disponible ainsi que DENSE_RANK

En gros tu dois ramener dans ta sous requete le nombre d'article ayant le même Repere et Mp (avec le COUNT fenetré)
Tu dois aussi ramener le nombre d'article par repere (avec une autre sous requete ou un max sur un DENSE_RANK)

Enfin tu as juste à ramener les lignes ou le premier nombre est égal au second si j'ai bien compris ta demande.
__________________
Je ne réponds pas aux questions techniques par MP, le forum est là pour cela.

La crypto c'est comme les flambys, une fois que tu as trouvé la languette tu as juste à tirer pour tout faire tomber.

(\ _ /)
(='.'=)
Voici Lapinou. Aidez le à conquérir le monde
(")-(") en le reproduisant
Drizzt [Drone38] est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 17h02   #8
Membre émérite
 
Avatar de Drizzt [Drone38]
 
Homme
Inscription : mai 2004
Messages : 739
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : mai 2004
Messages : 739
Points : 979
Points : 979
Citation:
Envoyé par dehorter olivier Voir le message
je ne comprends pas !

elle conserve pour tous les couples (nom, mp) pour lesquelles art se retrouve 2 fois et plus "HAVING Count(*) > 1"

ce n'est pas ce tu voulais ?
Oui mais ça ne gère pas le cas ou il n'y a qu'un article dans le repere. Car le count(*) va renvoyer 1 dans ce cas. Et il faut le remonter car il est commun avec lui meme.
__________________
Je ne réponds pas aux questions techniques par MP, le forum est là pour cela.

La crypto c'est comme les flambys, une fois que tu as trouvé la languette tu as juste à tirer pour tout faire tomber.

(\ _ /)
(='.'=)
Voici Lapinou. Aidez le à conquérir le monde
(")-(") en le reproduisant
Drizzt [Drone38] est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 17h19   #9
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
salut

Citation:
Mais maintenant, je voudrasi pour chaque repère, seulement les matières communes aux articles si il y en a plusieurs.
donc le "si il y en a plusieurs" fait référence aux matières et non au articles.
dans ce cas

n'ayant pas les fonctions de fenêtrage dans FIREBIRD, cela va m’être difficile de travailler dessus
et même si en bossant un peu il y aurait moyen de trouver un truc "plus classique" je laisse le fenêtrage à l'ouvrage
dehorter olivier est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 17h30   #10
Membre émérite
 
Avatar de Drizzt [Drone38]
 
Homme
Inscription : mai 2004
Messages : 739
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : mai 2004
Messages : 739
Points : 979
Points : 979
Voici une solution Oracle avec un seul fenetrage.
J'ai simplifié les jointures entre tables pour me faire gagner du temps, mais c'est normalement pas génant pour le fond du problème.

Il te reste à retrouver la bonne syntaxe chez toi.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
WITH 
Repere AS (SELECT 'Rep1' Nom FROM DUAL union ALL SELECT 'Rep2' FROM DUAL),
Article AS (SELECT 'Rep1' rep, 'Art1' Nom FROM dual union ALL SELECT 'Rep1' rep, 'Art2' Nom FROM dual
            union ALL SELECT 'Rep2', 'Art5' FROM dual),
Mp AS (SELECT 'Art1' art, 'MP1' Nom FROM dual union ALL SELECT 'Art1' art, 'MP2' Nom FROM dual
      union ALL SELECT 'Art1' art, 'MP3' Nom FROM dual union ALL SELECT 'Art1' art, 'MP4' Nom FROM dual
      union ALL SELECT 'Art2' art, 'MP1' Nom FROM dual union ALL SELECT 'Art2' art, 'MP2' Nom FROM dual
      union ALL SELECT 'Art2' art, 'MP3' Nom FROM dual union ALL SELECT 'Art5', 'MP1' FROM dual)
SELECT sel.Nom,
       Mp.Nom AS Mp
  FROM 
  (
    SELECT Repere.Nom,
           Article.Nom AS Art,
           COUNT(1) over(partition BY Repere.Nom ) AS n_art
       FROM Repere
        JOIN Article  ON Article.Rep = Repere.Nom    
  ) sel JOIN Mp ON Mp.art = sel.Art
GROUP BY sel.Nom, Mp.Nom, n_art
HAVING count(1) = n_art
__________________
Je ne réponds pas aux questions techniques par MP, le forum est là pour cela.

La crypto c'est comme les flambys, une fois que tu as trouvé la languette tu as juste à tirer pour tout faire tomber.

(\ _ /)
(='.'=)
Voici Lapinou. Aidez le à conquérir le monde
(")-(") en le reproduisant
Drizzt [Drone38] est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2011, 17h54   #11
Invité de passage
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 2
Points : 2
Merci bien

Je vais chercher un peu à partir de ta requête. Je vous tiens au courant.

Encore merci
Grinvald est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 15h03   #12
Invité de passage
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 12
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 12
Points : 2
Points : 2
J'ai finalement utilisé SELECT CASE WHEN ...

Merci à tous et à une prochaine fois
Grinvald 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 09h08.


 
 
 
 
Partenaires

Hébergement Web