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 :

Regroupement de table en colonnes


Sujet :

Langage SQL

  1. #1
    Membre expert
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 725
    Points : 3 338
    Points
    3 338
    Par défaut Regroupement de table en colonnes
    Bonjour à tous ,

    J'aimerais savoir s'il est possible de regrouper des tables (qui possède les même champs) mais avec un résultat en colonnes.

    Voici la définition de deux des tables :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /* Table 1 */
    CREATE TABLE [dbo].[MO_Fabrication](
    	[IdOuvrage] [int] NOT NULL,
    	[Famille] [tinyint] NOT NULL,
    	[Temps] [decimal](10, 4) NOT NULL,
     CONSTRAINT [PK_MO_Fabrication] PRIMARY KEY CLUSTERED 
    (
    	[IdOuvrage] ASC,
    	[Famille] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    ALTER TABLE [dbo].[MO_Fabrication]  WITH CHECK ADD  CONSTRAINT [FK_MO_Fabrication_Ouvrage] FOREIGN KEY([IdOuvrage])
    REFERENCES [dbo].[Ouvrage] ([ID])
    GO
     
    ALTER TABLE [dbo].[MO_Fabrication] CHECK CONSTRAINT [FK_MO_Fabrication_Ouvrage]
    GO
     
    /* Table 2 */
    CREATE TABLE [dbo].[MO_Dessin](
    	[IdOuvrage] [int] NOT NULL,
    	[Famille] [tinyint] NOT NULL,
    	[Temps] [decimal](10, 4) NOT NULL,
     CONSTRAINT [PK_MO_Dessin] PRIMARY KEY CLUSTERED 
    (
    	[IdOuvrage] ASC,
    	[Famille] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    ALTER TABLE [dbo].[MO_Dessin]  WITH CHECK ADD  CONSTRAINT [FK_MO_Dessin_Ouvrage] FOREIGN KEY([IdOuvrage])
    REFERENCES [dbo].[Ouvrage] ([ID])
    GO
     
    ALTER TABLE [dbo].[MO_Dessin] CHECK CONSTRAINT [FK_MO_Dessin_Ouvrage]
    GO
    Actuellement je les regroupes dans une vue de manière relativement simple avec un UNION ALL et deux INNER JOIN en plus sur deux tables complémentaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT d.CodeChantier, d.Code, o.Repere, o.Quantite, o.Unite, MO.Temps, MO.Type
    FROM  (
             SELECT        IdOuvrage, Temps, Type
             FROM            (SELECT        fab.IdOuvrage, fab.Temps, f.Libelle AS Type
             FROM            dbo.MO_Fabrication AS fab INNER JOIN
             dbo.Famille AS f ON f.Id = fab.Famille) AS Fabrication
             UNION ALL
             SELECT        IdOuvrage, Temps, Type
             FROM            (SELECT        dessin.IdOuvrage, dessin.Temps, 'BE' AS Type
             FROM            dbo.MO_Dessin AS dessin INNER JOIN
             dbo.Famille AS f ON f.Id = dessin.Famille) AS MO
    INNER JOIN dbo.Ouvrage AS o ON o.ID = MO.IdOuvrage
    INNER JOIN dbo.Devis AS d ON d.Code = o.CodeDevis
    Mais je souhaiterais les regrouper en colonnes, c'est à dire avoir quelque chose comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Devis.CodeChantier | Devis.Code | Ouvrage.Repere | Table1_Qte | Table1_Temps | Table2_Qte | Table2_Temps | ..... TableX_Qte | TableX_Temps
    A savoir qu'il ne peut pas y avoir plus d'une ligne pour un Ouvrage dans les Tables à liées, par contre il peux ne pas y avoir de lignes.
    Dans ce cas on mettrai la quantité et le temps à 0.

    Est-ce possible ?

    Merci à vous

    PS : Définition des tables Ouvrage et Devis si besoin :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    CREATE TABLE [dbo].[Ouvrage](
    	[ID] [int] IDENTITY(1,1) NOT NULL,
    	[CodeDevis] [nvarchar](15) NOT NULL,
    	[IdTranche] [nvarchar](4) NOT NULL,
    	[Libelle] [nvarchar](255) NOT NULL,
    	[Repere] [nvarchar](50) NOT NULL,
    	[Famille] [tinyint] NOT NULL,
    	[Quantite] [decimal](10, 4) NOT NULL,
    	[Unite] [nvarchar](5) NOT NULL,
    	[Temps] [decimal](10, 4) NOT NULL,
     CONSTRAINT [PK_Ouvrages] PRIMARY KEY CLUSTERED 
    (
    	[ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    CREATE TABLE [dbo].[Devis](
    	Code [nvarchar](15) NOT NULL,
    	[CodeChantier] [nvarchar](8) NOT NULL,
    	[Libelle] [nvarchar](255) NOT NULL,
     CONSTRAINT [PK_Devis] PRIMARY KEY CLUSTERED 
    (
    	Code ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    il vous suffit de faire une jointure externe (FULL [OUTER] JOIN) entre vos deux tables.

  3. #3
    Membre expert
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 725
    Points : 3 338
    Points
    3 338
    Par défaut
    Le FULL JOIN ne met pas en colonne un résultat qui est en ligne.

    Il réalise juste une jointure au même titre que l'INNER JOIN

    Je ne comprends pas ta réponse

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    je parlais d'un FULL JOIN en rempalcement de votre UNION ( et non en remplacement de vos jointures actuelles)

    quelque chose comme :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT	d.CodeChantier, d.Code, o.Repere, o.Quantite, o.Unite, fab.Temps AS Temps1, fab.Type AS Type1,dessin.Temps as temps2, 'BE' AS Type as type2
    FROM			dbo.MO_Fabrication AS fab 
    				INNER JOIN		dbo.Famille AS f ON f.Id = fab.Famille
    FULL OUTER JOIN	dbo.MO_Dessin AS dessin 
    				INNER JOIN      dbo.Famille AS f ON f.Id = dessin.Famille
    		ON	dessin.IdOuvrage = fab.IdOuvrage
    INNER JOIN dbo.Ouvrage AS o 
    	ON o.ID = COALESCE(dessin.IdOuvrage	fab.IdOuvrage)
    INNER JOIN dbo.Devis AS d ON d.Code = o.CodeDevis
    Mais il y a d'autres façons de faire (sans doute plus élégantes), par exemple en faisant des jointures externes unilatérales sur la table ouvrage.

    Cependant, j'ai l'impression qu'il y une erreur de modélisation derrière tout ça, et qu'il faudrait mettre en place de l'héritage.

  5. #5
    Membre expert
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 725
    Points : 3 338
    Points
    3 338
    Par défaut
    Jointures externes, mais du coup, comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     SELECT Ouvrage.ID, Ouvrage.Repere, Ouvrage.Quantite, Ouvrage.Unite, SUM(MO_Fabrication.Temps) TempsFab, SUM(MO_Dessin.Temps) TempsDessin
     FROM Ouvrage, MO_Fabrication, MO_Dessin
     WHERE MO_Fabrication.IdOuvrage = Ouvrage.ID
     AND MO_Dessin.IdOuvrage = Ouvrage.ID
     GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Quantite, Ouvrage.Unite
    Edit : FUlL OUTER JOIN
    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
     SELECT Ouvrage.ID, Ouvrage.Repere, Ouvrage.Quantite, Ouvrage.Unite
    	   ,SUM(Fab_Acier.Temps) TempsFabAcier
    	   ,SUM(Fab_Alu.Temps) TempsFabAlu
    	   ,SUM(Fab_Tol.Temps) TempsFabTol
    	   ,SUM(Des_Acier.Temps) TempsDesAcier
    	   ,SUM(Des_Alu.Temps) TempsDesAlu
    	   ,SUM(Des_Tol.Temps) TempsDesTol
     FROM Ouvrage
     FULL OUTER JOIN (SELECT * FROM MO_Fabrication WHERE Famille = 1) Fab_Acier ON Fab_Acier.IdOuvrage = Ouvrage.ID
     FULL OUTER JOIN (SELECT * FROM MO_Fabrication WHERE Famille = 2) Fab_Alu ON Fab_Alu.IdOuvrage = Ouvrage.ID
     FULL OUTER JOIN (SELECT * FROM MO_Fabrication WHERE Famille = 2) Fab_Tol ON Fab_Tol.IdOuvrage = Ouvrage.ID
     FULL OUTER JOIN (SELECT * FROM MO_Dessin WHERE Famille = 1) Des_Acier ON Des_Acier.IdOuvrage = Ouvrage.ID
     FULL OUTER JOIN (SELECT * FROM MO_Dessin WHERE Famille = 2) Des_Alu ON Des_Alu.IdOuvrage = Ouvrage.ID
     FULL OUTER JOIN (SELECT * FROM MO_Dessin WHERE Famille = 2) Des_Tol ON Des_Tol.IdOuvrage = Ouvrage.ID
     GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Quantite, Ouvrage.Unite
    Cela correspond à ce que je souhaite avoir comme résultat, qu'en pensez vous ?

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    dans ce cas... plutôt comme ceci, qui évite les nombreuses sous requetes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SELECT Ouvrage.ID, Ouvrage.Repere, Ouvrage.Quantite, Ouvrage.Unite
    	   ,SUM(CASE WHEN fab.famille = 1 THEN fab.Temps END) TempsFabAcier
    	   ,SUM(CASE WHEN fab.famille = 2 THEN fab.Temps END) TempsFabAlu
    	   ,SUM(CASE WHEN fab.famille = 2 THEN fab.Temps END) TempsFabTol
    	   ,SUM(CASE WHEN dessin.famille = 1 THEN fab.Temps END) TempsDesAcier
    	   ,SUM(CASE WHEN dessin.famille = 2 THEN fab.Temps END) TempsDesAlu
    	   ,SUM(CASE WHEN dessin.famille = 2 THEN fab.Temps END) TempsDesTol
    FROM Ouvrage
    LEFT JOIN MO_Fabrication fab
    	ON	fab.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_Dessin dessin
    	ON	dessin.rage = Ouvrage.ID
    GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Quantite, Ouvrage.Unite

  7. #7
    Membre expert
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 725
    Points : 3 338
    Points
    3 338
    Par défaut
    Merci !
    Réponse tardive, mais avec ta requête j'ai un souci.

    Avec toutes les tables concernées :

    Ma requête :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    SELECT        MAX(dbo.Devis.CodeChantier) AS CodeChantier, MAX(dbo.Devis.Code) AS CodeDevis, dbo.Ouvrage.ID AS IdOuvrage, dbo.Ouvrage.Repere AS RepereOuvrage, dbo.Ouvrage.Libelle AS LibelleOuvrage, 
                             dbo.Ouvrage.Quantite AS QteOuvrage, dbo.Ouvrage.Unite AS UniteOuvrage, SUM(Fab_Acier.Temps) AS TempsFabAcier, SUM(Fab_Alu.Temps) AS TempsFabAlu, SUM(Fab_Tol.Temps) AS TempsFabTol, 
                             SUM(Des_Acier.Temps) AS TempsDesAcier, SUM(Des_Alu.Temps) AS TempsDesAlu, SUM(Des_Tol.Temps) AS TempsDesTol, SUM(dbo.MO_CT.Temps) AS TempsCT, SUM(dbo.MO_Pose.Temps) 
                             AS TempsPose
    FROM            dbo.Ouvrage FULL OUTER JOIN
                                 (SELECT        IdOuvrage, Famille, Temps
                                   FROM            dbo.MO_Fabrication
                                   WHERE        (Famille = 1)) AS Fab_Acier ON Fab_Acier.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                                 (SELECT        IdOuvrage, Famille, Temps
                                   FROM            dbo.MO_Fabrication AS MO_Fabrication_2
                                   WHERE        (Famille = 2)) AS Fab_Alu ON Fab_Alu.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                                 (SELECT        IdOuvrage, Famille, Temps
                                   FROM            dbo.MO_Fabrication AS MO_Fabrication_1
                                   WHERE        (Famille = 3)) AS Fab_Tol ON Fab_Tol.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                                 (SELECT        IdOuvrage, Famille, Temps
                                   FROM            dbo.MO_Dessin
                                   WHERE        (Famille = 1)) AS Des_Acier ON Des_Acier.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                                 (SELECT        IdOuvrage, Famille, Temps
                                   FROM            dbo.MO_Dessin AS MO_Dessin_2
                                   WHERE        (Famille = 2)) AS Des_Alu ON Des_Alu.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                                 (SELECT        IdOuvrage, Famille, Temps
                                   FROM            dbo.MO_Dessin AS MO_Dessin_1
                                   WHERE        (Famille = 3)) AS Des_Tol ON Des_Tol.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                             dbo.MO_CT ON dbo.MO_CT.IdOuvrage = dbo.Ouvrage.ID FULL OUTER JOIN
                             dbo.MO_Pose ON dbo.MO_Pose.IdOuvrage = dbo.Ouvrage.ID INNER JOIN
                             dbo.Devis ON dbo.Devis.Code = dbo.Ouvrage.CodeDevis
    GROUP BY dbo.Ouvrage.ID, dbo.Ouvrage.Repere, dbo.Ouvrage.Libelle, dbo.Ouvrage.Quantite, dbo.Ouvrage.Unite
    Ta requête :
    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
    17
    18
    19
    20
    21
    SELECT MAX(Devis.CodeChantier) CodeChantier, MAX(Devis.Code) CodeDevis, Ouvrage.ID IdOuvrage, Ouvrage.Repere RepereOuvrage, Ouvrage.Libelle LibelleOuvrage, Ouvrage.Quantite QteOuvrage, Ouvrage.Unite UniteOuvrage
    	   ,SUM(CASE WHEN Fab.famille = 1 THEN Fab.Temps END) TempsFabAcier
    	   ,SUM(CASE WHEN Fab.famille = 2 THEN Fab.Temps END) TempsFabAlu
    	   ,SUM(CASE WHEN Fab.famille = 3 THEN Fab.Temps END) TempsFabTol
    	   ,SUM(CASE WHEN Dessin.famille = 1 THEN Dessin.Temps END) TempsDesAcier
    	   ,SUM(CASE WHEN Dessin.famille = 2 THEN Dessin.Temps END) TempsDesAlu
    	   ,SUM(CASE WHEN Dessin.famille = 3 THEN Dessin.Temps END) TempsDesTol
    	   ,SUM(CT.Temps) TempsCT
    	   ,SUM(Pose.Temps) TempsPose
    FROM Ouvrage
    LEFT JOIN MO_Fabrication Fab
    	ON	Fab.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_Dessin Dessin
    	ON	Dessin.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_CT CT
    	ON CT.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_Pose Pose
    	ON Pose.IdOuvrage = Ouvrage.ID
    INNER JOIN Devis
    	ON Devis.Code = Ouvrage.CodeDevis
    GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Libelle, Ouvrage.Quantite, Ouvrage.Unite
    Pour un OuvrageId donnée, avec la mienne j'ai en résultat ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    461	16.0055	484	139F	Plus values pour modification du garde-corps	135.0000	ML	1.7500	0.2500	NULL	0.0800	NULL	NULL	0.0800	NULL
    Avec la tienne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    461	16.0055	484	139F	Plus values pour modification du garde-corps	135.0000	ML	1.7500	0.2500	NULL	0.1600	NULL	NULL	0.1600	NULL
    Je constate que le TempsCT et le TempsDessin sont doublés avec ta version, alors qu'avec la mienne le temps est correcte.

    Pour info, sur cet Ouvrage (id 484), il y a deux ligne dans la table MO_Fabrication (une pour famille 1 et une pour famille 2), j'imagine que c'est ça qui provoque le doublage.

    Comment l'éviter ?

    Merci

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Vous pouvez effectuer le pivot dans des sous requete au niveau des jointure, afin que la jointure n'opére que sur une ligne à chaque fois?

    Ou vous pouvez ajouter la table des famille et restreindre dessus lors des jointures :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    SELECT MAX(Devis.CodeChantier) CodeChantier, MAX(Devis.Code) CodeDevis, Ouvrage.ID IdOuvrage, Ouvrage.Repere RepereOuvrage, Ouvrage.Libelle LibelleOuvrage, Ouvrage.Quantite QteOuvrage, Ouvrage.Unite UniteOuvrage
    	   ,SUM(CASE WHEN Fab.famille = 1 THEN Fab.Temps END) TempsFabAcier
    	   ,SUM(CASE WHEN Fab.famille = 2 THEN Fab.Temps END) TempsFabAlu
    	   ,SUM(CASE WHEN Fab.famille = 3 THEN Fab.Temps END) TempsFabTol
    	   ,SUM(CASE WHEN Dessin.famille = 1 THEN Dessin.Temps END) TempsDesAcier
    	   ,SUM(CASE WHEN Dessin.famille = 2 THEN Dessin.Temps END) TempsDesAlu
    	   ,SUM(CASE WHEN Dessin.famille = 3 THEN Dessin.Temps END) TempsDesTol
    	   ,SUM(CT.Temps) TempsCT
    	   ,SUM(Pose.Temps) TempsPose
    FROM Ouvrage
    CROSS Famille f
    LEFT JOIN MO_Fabrication Fab
    	ON	Fab.IdOuvrage = Ouvrage.ID
            AND   Fab.IdFamille = F.IdFamille
    LEFT JOIN MO_Dessin Dessin
    	ON	Dessin.IdOuvrage = Ouvrage.ID
            AND   Dessin.IdFamille = F.IdFamille
    LEFT JOIN MO_CT CT
    	ON CT.IdOuvrage = Ouvrage.ID
            AND   CT.IdFamille = F.IdFamille --supposition car pas le ddl de la table...
    LEFT JOIN MO_Pose Pose
    	ON Pose.IdOuvrage = Ouvrage.ID
    INNER JOIN Devis
    	ON Devis.Code = Ouvrage.CodeDevis
    GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Libelle, Ouvrage.Quantite, Ouvrage.Unite

  9. #9
    Membre expert
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 725
    Points : 3 338
    Points
    3 338
    Par défaut
    Arf !
    Les tables CT et Pose n'ont pas de champs Famille car elle ne sont jamais lié à une famille.
    MO_CT (MO_Pose identique)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE [dbo].[MO_CT](
    	[IdOuvrage] [int] NOT NULL,
    	[Temps] [decimal](10, 4) NOT NULL,
     CONSTRAINT [PK_MO_CT] PRIMARY KEY CLUSTERED 
    (
    	[IdOuvrage] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    MO_Fabrication (MO_Dessin identique)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE [dbo].[MO_Fabrication](
    	[IdOuvrage] [int] NOT NULL,
    	[Famille] [tinyint] NOT NULL,
    	[Temps] [decimal](10, 4) NOT NULL,
     CONSTRAINT [PK_MO_Fabrication] PRIMARY KEY CLUSTERED 
    (
    	[IdOuvrage] ASC,
    	[Famille] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    Ouvrage
    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
    CREATE TABLE [dbo].[Ouvrage](
    	[ID] [int] IDENTITY(1,1) NOT NULL,
    	[CodeDevis] [nvarchar](15) NOT NULL,
    	[IdTranche] [nvarchar](4) NOT NULL,
    	[Libelle] [nvarchar](255) NOT NULL,
    	[Repere] [nvarchar](50) NOT NULL,
    	[Famille] [tinyint] NOT NULL,
    	[Quantite] [decimal](10, 4) NOT NULL,
    	[Unite] [nvarchar](5) NOT NULL,
    	[Temps] [decimal](10, 4) NOT NULL,
     CONSTRAINT [PK_Ouvrages] PRIMARY KEY CLUSTERED 
    (
    	[ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    On peux faire autrement ?

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    essayez ceci

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    SELECT 
    		  MAX(Devis.CodeChantier) CodeChantier
    		, MAX(Devis.Code) CodeDevis
    		, Ouvrage.ID IdOuvrage
    		, Ouvrage.Repere RepereOuvrage
    		, Ouvrage.Libelle LibelleOuvrage
    		, Ouvrage.Quantite QteOuvrage
    		, Ouvrage.Unite UniteOuvrage
    		, TempsFabAcier
    		, TempsFabAlu
    		, TempsFabTol	
    		, TempsDesAcier
    		, TempsDesAlu
    		, TempsDesTol
    		, SUM(CT.Temps) TempsCT
    		, SUM(Pose.Temps) TempsPose
    FROM Ouvrage
    LEFT JOIN (
    	SELECT	IdOuvrage
    		,	SUM(CASE WHEN Fab.famille = 1 THEN Fab.Temps END) TempsFabAcier
    		,	SUM(CASE WHEN Fab.famille = 2 THEN Fab.Temps END) TempsFabAlu
    		,	SUM(CASE WHEN Fab.famille = 3 THEN Fab.Temps END) TempsFabTol	
    	FROM MO_Fabrication 
    	GROUP BY IdOuvrage
    	) Fab
    	ON	Fab.IdOuvrage = Ouvrage.ID
    LEFT JOIN (
    	SELECT IdOuvrage
    		,	SUM(CASE WHEN Dessin.famille = 1 THEN Dessin.Temps END) TempsDesAcier
    		,	SUM(CASE WHEN Dessin.famille = 2 THEN Dessin.Temps END) TempsDesAlu
    		,	SUM(CASE WHEN Dessin.famille = 3 THEN Dessin.Temps END) TempsDesTol
    	FROM	MO_Dessin 
    	GROUP BY IdOuvrage
    	) Dessin
    	ON	Dessin.IdOuvrage = Ouvrage.ID
            AND   Dessin.IdFamille = F.IdFamille
    LEFT JOIN MO_CT CT
    	ON CT.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_Pose Pose
    	ON Pose.IdOuvrage = Ouvrage.ID
    INNER JOIN Devis
    	ON Devis.Code = Ouvrage.CodeDevis
    GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Libelle, Ouvrage.Quantite, Ouvrage.Unite
    sinon postez un jeu d'essai CREATE TABLE + INSERT

  11. #11
    Membre expert
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2004
    Messages : 2 725
    Points : 3 338
    Points
    3 338
    Par défaut
    J'ai corrigé (il manquait les SUM sur les Temps Fab et Des) :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    SELECT 
    		  MAX(Devis.CodeChantier) CodeChantier
    		, MAX(Devis.Code) CodeDevis
    		, Ouvrage.ID IdOuvrage
    		, Ouvrage.Repere RepereOuvrage
    		, Ouvrage.Libelle LibelleOuvrage
    		, Ouvrage.Quantite QteOuvrage
    		, Ouvrage.Unite UniteOuvrage
    		, SUM(TempsFabAcier) TempsFabAcier
    		, SUM(TempsFabAlu) TempsFabAlu
    		, SUM(TempsFabTol) TempsFabTol
    		, SUM(TempsDesAcier) TempsDesAcier
    		, SUM(TempsDesAlu) TempsDesAlu
    		, SUM(TempsDesTol) TempsDesTol
    		, SUM(CT.Temps) TempsCT
    		, SUM(Pose.Temps) TempsPose
    FROM Ouvrage
    LEFT JOIN (
    	SELECT	IdOuvrage
    		,	SUM(CASE WHEN famille = 1 THEN Temps END) TempsFabAcier
    		,	SUM(CASE WHEN famille = 2 THEN Temps END) TempsFabAlu
    		,	SUM(CASE WHEN famille = 3 THEN Temps END) TempsFabTol	
    	FROM MO_Fabrication 
    	GROUP BY IdOuvrage
    	) Fab
    	ON	Fab.IdOuvrage = Ouvrage.ID
    LEFT JOIN (
    	SELECT IdOuvrage
    		,	SUM(CASE WHEN famille = 1 THEN Temps END) TempsDesAcier
    		,	SUM(CASE WHEN famille = 2 THEN Temps END) TempsDesAlu
    		,	SUM(CASE WHEN famille = 3 THEN Temps END) TempsDesTol
    	FROM	MO_Dessin 
    	GROUP BY IdOuvrage
    	) Dessin
    	ON	Dessin.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_CT CT
    	ON CT.IdOuvrage = Ouvrage.ID
    LEFT JOIN MO_Pose Pose
    	ON Pose.IdOuvrage = Ouvrage.ID
    INNER JOIN Devis
    	ON Devis.Code = Ouvrage.CodeDevis
    GROUP BY Ouvrage.ID, Ouvrage.Repere, Ouvrage.Libelle, Ouvrage.Quantite, Ouvrage.Unite
    C'est ok, je retrouve les même temps

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

Discussions similaires

  1. Tables et colonnes
    Par Acti dans le forum SQL Procédural
    Réponses: 9
    Dernier message: 08/12/2005, 13h00
  2. Réponses: 10
    Dernier message: 01/12/2005, 09h47
  3. [admin] Commentaires tables et colonnes
    Par mjolymelot dans le forum Oracle
    Réponses: 2
    Dernier message: 22/11/2005, 08h37
  4. [débutant] Comment regrouper deux tables ?
    Par maysa dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 27/10/2004, 18h50
  5. regrouper deux tables
    Par Shabata dans le forum Langage SQL
    Réponses: 4
    Dernier message: 19/05/2003, 15h02

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