web-dev-qa-db-fra.com

Inscrivez-vous pour obtenir toutes les lignes de la première table avec NULLS de la deuxième table

J'ai deux tables (tblReps et tblDailyWorkingTime). La table tblReps, c'est-à-dire la première, le premier, retourne 37 lignes, mais lorsque je le rejointe avec la deuxième table, je reçois 36 lignes car la deuxième table n'a que 36 rangées correspondant à la première table.

Comment puis-je revenir aux 37 rangées avec un résultat nul pour la rangée qui n'était pas assortie?

Voici la requête que j'ai jusqu'à présent:

SELECT 
    tblReps.[sName] AS 'RepName',
    tblReps.sNote AS 'Type',
    RIGHT(CAST(tblDaily.sDateAndTimeStart  AS smalldatetime), 8) AS 'DayStarted'

FROM 
    [tblRepresentatives] AS tblReps

FULL OUTER JOIN 
    tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode 

WHERE 
    tblDaily.sDate = CAST(GETDATE() AS DATE)
    AND tblReps.[sActive] = 'True'
3
Mark Blackburn

Tout d'abord, le type de jointure à utiliser dans ce cas est une jointure gauche:

...
FROM 
    [tblRepresentatives] AS tblReps

LEFT OUTER JOIN 
    tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode 
...

Dans votre cas spécifique, vous pouvez toujours utiliser FULL parce que cette condition en WHERE _ la transformerait en une joindre à gauche:

tblReps.[sActive] = 'True'

Mais il vaut mieux exprimer l'intention avec précision.

Le même effet qui transforme votre jointure complète dans une jointe à gauche est en fait responsable de la 37e rangée manquante que vous attendiez. Plus spécifiquement, cet autre WHERE condition:

tblDaily.sDate = CAST(GETDATE() AS DATE)

transforme votre jointure plus loin en une Join interne. C'est pourquoi la 37e rangée est manquante de la sortie.

La raison de cela se produisait est-ce. La clause FROM renvoie une null dans tblDaily.sDate Pour la ligne inégalée. Parce que la clause WHERE exécute logiquement après le FROM, le prédicat mentionné ci-dessus exclut la ligne inégalée, puisque NULL = CAST(GETDATE() AS DATE) n'évalue pas à vrai .

Ce que vous devez faire à la place est de déplacer la condition sDate condition au sous-paragraphe ON:

...
FROM 
    [tblRepresentatives] AS tblReps

LEFT OUTER JOIN 
    tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode
                                   AND tblDaily.sDate = CAST(GETDATE() AS DATE)

WHERE 
    tblReps.[sActive] = 'True'

De cette façon, le côté droit de la jointure est filtré sur tblDaily.sDate = CAST(GETDATE() AS DATE) -avant La jointure a lieu. Par conséquent, la requête retournera les 37 lignes attendues de tblReps complétée soit avec des données correspondantes de tblDaily ou avec des nulls.

8
Andriy M