web-dev-qa-db-fra.com

Multiple FULL OUTER JOIN sur plusieurs tables

J'ai plusieurs jointures externes

SELECT  A.column2
        , B.column2
        , C.column2
FROM 
(
    (SELECT month, column2 FROM table1) A
    FULL OUTER JOIN
    (SELECT month, column2 FROM table2) B on A.month= B.month
    FULL OUTER JOIN 
    (SELECT month, column2 FROM table3) C on A.month= C.month
)

Maintenant, la dernière jointure a un problème, elle se répète lorsque le mois de A est supérieur à B, mais si B a plus de mois que A, nous avons JOIN EXTERIEUR en C avec le mois de A qui se répète maintenant, donc je suppose qu'avoir une jointure externe complète dans deux tables pourraient résoudre le problème ?? Des liens profonds ??

Exemple de données (incorrect)

╔════════════╦═════════╦═════════════╗
║  Revenue   ║ Budget  ║ ActualMonth ║
╠════════════╬═════════╬═════════════╣
║     6.9172 ║ 3.5046  ║ Jan         ║
║     7.3273 ║ 3.7383  ║ Feb         ║
║     7.3273 ║ 3.9719  ║ Mar         ║
║     7.2726 ║ 4.2056  ║ Apr         ║
║     7.2595 ║ 6.7757  ║ May         ║
║     7.2726 ║ 6.7757  ║ Jun         ║
║     0.41   ║ 0.00    ║ Jul         ║
║     0.41   ║ 0.00    ║ Aug         ║
║     0.41   ║ 0.00    ║ Sep         ║
║     0.41   ║ 0.00    ║ Oct         ║
║     7.4696 ║ 0.00    ║ Nov         ║
║     7.4696 ║ 0.00    ║ Dec         ║
║     0.00   ║ 9.3457  ║ Sep         ║
║     0.00   ║ 16.3551 ║ Dec         ║
║     0.00   ║ 6.3084  ║ Jul         ║
║     0.00   ║ 14.0186 ║ Oct         ║
║     0.00   ║ 16.3551 ║ Nov         ║
║     0.00   ║ 6.1915  ║ Aug         ║
╚════════════╩═════════╩═════════════╝

Données correctes

╔════════════╦═════════╦═════════════╗
║  Revenue   ║ Budget  ║ ActualMonth ║
╠════════════╬═════════╬═════════════╣
║     6.9172 ║ 3.5046  ║ Jan         ║
║     7.3273 ║ 3.7383  ║ Feb         ║
║     7.3273 ║ 3.9719  ║ Mar         ║
║     7.2726 ║ 4.2056  ║ Apr         ║
║     7.2595 ║ 6.7757  ║ May         ║
║     7.2726 ║ 6.7757  ║ Jun         ║
║     0.41   ║ 6.3084  ║ Jul         ║
║     0.41   ║ 6.1915  ║ Aug         ║
║     0.41   ║ 9.3457  ║ Sep         ║
║     0.41   ║ 14.0186 ║ Oct         ║
║     7.4696 ║ 16.3551 ║ Nov         ║
║     7.4696 ║ 16.3551 ║ Dec         ║
╚════════════╩═════════╩═════════════╝
27
brykneval
SELECT  A.column2
        , B.column2
        , C.column2
FROM 
(
    (SELECT month, column2 FROM table1) A
    FULL OUTER JOIN
    (SELECT month, column2 FROM table2) B on A.month= B.month
    FULL OUTER JOIN 
    (SELECT month, column2 FROM table3) C on ISNULL(A.month, B.month) = C.month
)
36
Serge

Pour ce faire, vous pouvez créer une table "d'ancrage" à partir de toutes les données possibles des trois tables, puis utiliser left outer join:

select
    A.column2,
    B.column2,
    C.column2
from (
    select distinct month from table1
    union
    select distinct month from table2
    union
    select distinct month from table3
) as X
    left outer join table1 as A on A.month = X.month
    left outer join table2 as B on B.month = X.month
    left outer join table3 as C on C.month = X.month
7
Roman Pekar

Je peux penser à deux façons de résoudre ce problème, selon la logique réelle de définir les résultats souhaités.

La première, et la plus infaillible, consiste à utiliser GROUP BY month et à utiliser des fonctions d'agrégation comme MAX (colonne2) pour obtenir uniquement les lignes non nulles, ou s'il y a plusieurs lignes non nulles que vous souhaitez ajouter, utilisez SOMME(). C'est la meilleure solution s'il existe une fonction d'agrégation qui remplit votre intention logique.

Une autre consiste à inclure plus de conditions dans votre JOIN, comme "WHERE a.month = b.month AND b.column2> 0", mais cela ne résoudra toujours pas le problème s'il peut y avoir plus d'une ligne non nulle.

3
Tab Alleman

Utilisez l'option avec la fonction COALESCE pour déterminer un regroupement de colonnes.

SELECT COALESCE(t1.Month, t2.Month, t3.Month) AS Month, 
       SUM(ISNULL(t1.Col1, 0)) AS t1Col1, 
       SUM(ISNULL(t2.Col1, 0)) AS t2Col1, 
       SUM(ISNULL(t3.Col1, 0)) AS t3Col1
FROM dbo.table1 t1 FULL OUTER JOIN dbo.table2 t2 ON t1.Month = t2.Month
                   FULL OUTER JOIN dbo.table3 t3 ON t1.Month = t3.Month
GROUP BY COALESCE(t1.Month, t2.Month, t3.Month)
2

quelque chose comme

select month, sum(a) a,  sum(b) b, sum(c) c from (
  SELECT month, column2 A, 0 B, 0 C FROM table1 
    union 
  SELECT month, 0 A, column2 B, 0 C FROM table2
    union 
  SELECT month, 0 A, 0 B, column2 C FROM table3
) x
group by month
1
Ian Kenney