SQL différentes jointures ne faisant aucune différence pour résultat

J'essaie d'écrire un programme rapide (ha!) Pour organiser certaines de mes informations financières. Ce que je souhaite idéalement, c'est une requête qui returnnera tous les loggings contenant des informations financières à partir de TableA. Il devrait y avoir une ligne pour chaque mois, mais dans les cas où il n'y a pas eu de transactions pendant un mois, il n'y aura pas d'logging. Je reçois des résultats comme ceci:


SELECT Period,Year,TotalValue FROM TableA WHERE Year='1997' 

Résultat:

 Period Year TotalValue 1 1997 298.16 2 1997 435.25 4 1997 338.37 8 1997 336.07 9 1997 578.97 11 1997 361.23 

En joignant sur une table (bien une vue dans cette instance) qui contient juste un champ Period avec des valeurs de 1 à 12, je m'attends à get quelque chose comme ceci:


 SELECT p.Period,a.Year,a.TotalValue FROM Periods AS p LEFT JOIN TableA AS a ON p.Period = a.Period WHERE Year='1997' 

Résultat:

 Period Year TotalValue 1 1997 298.16 2 1997 435.25 3 NULL NULL 4 1997 338.37 5 NULL NULL 6 NULL NULL 7 NULL NULL 8 1997 336.07 9 1997 578.97 10 NULL NULL 11 1997 361.23 12 NULL NULL 

Ce que je reçois en réalité, c'est le même résultat, peu importe comment je le rejoins (sauf CROSS JOIN qui devient fou, mais ce n'est vraiment pas ce que je voulais, c'était juste pour voir si des jointures différentes faisaient quoi que ce soit). C'est-à-dire, il n'y a pas d'loggings NULL, il returnne seulement les loggings qui existent avec des périodes correspondantes dans le Tableau A au lieu de 12 loggings de 1 à 12 indépendamment. LEFT JOIN, RIGHT JOIN, INNER JOIN ne parviennent pas à fournir les loggings NULL que j'attends.

Y at-il quelque chose d'évident que je me trompe dans le JOIN? Est-ce important que je me joigne à une vue?


Edit En utilisant l'exemple de Mark Byers, j'ai essayé ce qui suit:

 SELECT p.Period,a.Year,a.TotalValue FROM Periods AS p LEFT JOIN TableA AS a ON (p.Period = a.Period) AND (a.Year = '1997') 

Résultat:

 Period Year TotalValue 1 1997 298.16 2 1997 435.25 4 1997 338.37 8 1997 336.07 9 1997 578.97 11 1997 361.23 

Il obtient effectivement le même résultat d'une manière différente, n'obtenant toujours pas les inputs NULL attendues pour 3,5,6,7, etc.


Un grand merci à Mark Byers pour avoir aidé à find la solution finale, qui pour l'logging était:

 SELECT p.Period, a.YEAR, SUM(a.Value) as TotalValue FROM Periods as p LEFT JOIN TableA as a ON d.Period = p.Period AND a.Year = '1997' GROUP BY p.Period,a.Year,a.PERIOD ORDER BY p.Period,a.Year; 

En pratique, il y a aussi un champ LedgerID qui est groupé par, bien que le résultat final rest le même: le filtrage doit être fait sur le JOIN, pas sur le résultat du JOIN.

C'est faux:

 WHERE Year='1997' 

Vous voulez des lignes où Year est 1997 ou est NULL mais les NULL sont filtrés à cause de cette clause WHERE. Utilisez ceci à la place:

 LEFT JOIN TableA AS a ON p.Period = a.Period AND Year = '1997' 

Notez également que vous n'avez pas besoin de conserver la table Periods . Vous pouvez également le générer dynamicment en utilisant un CTE récursif . Votre CTE récursif devrait ressembler à ceci:

 WITH Periods (Period) AS ( SELECT 1 UNION ALL SELECT Period + 1 FROM Periods WHERE Period < 12 ) SELECT * FROM Periods 

Je pense que ce dont tu as besoin est LEFT OUTER JOIN

Je pense que vous cherchez un

 FULL OUTER JOIN 

car pour chaque "année" NULL, son "TotalValue" correspondant est également NULL!