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'
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.