JOIN to obtain all the rows from the first table along with NULLs from the second table
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{
margin-bottom:0;
}
I have two tables (tblReps
and tblDailyWorkingTime
). The tblReps
table, i.e., the first one, returns 37 rows, but when I JOIN it with the second table I get 36 rows as the second table only has 36 rows that match the first table.
How do I go about getting the 37 rows back with a NULL result for the row that was not matched?
Here is the query that I have so far:
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'
sql-server join
add a comment
|
I have two tables (tblReps
and tblDailyWorkingTime
). The tblReps
table, i.e., the first one, returns 37 rows, but when I JOIN it with the second table I get 36 rows as the second table only has 36 rows that match the first table.
How do I go about getting the 37 rows back with a NULL result for the row that was not matched?
Here is the query that I have so far:
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'
sql-server join
add a comment
|
I have two tables (tblReps
and tblDailyWorkingTime
). The tblReps
table, i.e., the first one, returns 37 rows, but when I JOIN it with the second table I get 36 rows as the second table only has 36 rows that match the first table.
How do I go about getting the 37 rows back with a NULL result for the row that was not matched?
Here is the query that I have so far:
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'
sql-server join
I have two tables (tblReps
and tblDailyWorkingTime
). The tblReps
table, i.e., the first one, returns 37 rows, but when I JOIN it with the second table I get 36 rows as the second table only has 36 rows that match the first table.
How do I go about getting the 37 rows back with a NULL result for the row that was not matched?
Here is the query that I have so far:
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'
sql-server join
sql-server join
edited Jun 3 at 21:07
MDCCL
7,2893 gold badges20 silver badges48 bronze badges
7,2893 gold badges20 silver badges48 bronze badges
asked May 27 at 13:06
Mark BlackburnMark Blackburn
182 bronze badges
182 bronze badges
add a comment
|
add a comment
|
1 Answer
1
active
oldest
votes
First of all, the correct type of join to use in this case is a left join:
...
FROM
[tblRepresentatives] AS tblReps
LEFT OUTER JOIN
tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode
...
In your specific case, you could still use FULL
because this condition in WHERE
would turn it into a left join anyway:
tblReps.[sActive] = 'True'
But it is better to express the intent accurately.
The same effect that turns your full join into a left join is actually responsible for the missing 37th row that you expected. More specifically, this other WHERE
condition:
tblDaily.sDate = CAST(GETDATE() AS DATE)
transforms your join further into an inner join. That is why the 37th row is missing from the output.
The reason for that happening is this. The FROM
clause returns a null in tblDaily.sDate
for the unmatched row. Because the WHERE
clause logically executes after the FROM
, the above-mentioned predicate excludes the unmatched row, since NULL = CAST(GETDATE() AS DATE)
does not evaluate to True.
What you need to do instead is move the sDate
condition to the ON
subclause:
...
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'
That way the right-hand side of the join is filtered on tblDaily.sDate = CAST(GETDATE() AS DATE)
before the join takes place. Consequently, the query will return the expected 37 rows from tblReps
complemented either with matching data from tblDaily
or with nulls.
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
add a comment
|
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f239140%2fjoin-to-obtain-all-the-rows-from-the-first-table-along-with-nulls-from-the-secon%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
First of all, the correct type of join to use in this case is a left join:
...
FROM
[tblRepresentatives] AS tblReps
LEFT OUTER JOIN
tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode
...
In your specific case, you could still use FULL
because this condition in WHERE
would turn it into a left join anyway:
tblReps.[sActive] = 'True'
But it is better to express the intent accurately.
The same effect that turns your full join into a left join is actually responsible for the missing 37th row that you expected. More specifically, this other WHERE
condition:
tblDaily.sDate = CAST(GETDATE() AS DATE)
transforms your join further into an inner join. That is why the 37th row is missing from the output.
The reason for that happening is this. The FROM
clause returns a null in tblDaily.sDate
for the unmatched row. Because the WHERE
clause logically executes after the FROM
, the above-mentioned predicate excludes the unmatched row, since NULL = CAST(GETDATE() AS DATE)
does not evaluate to True.
What you need to do instead is move the sDate
condition to the ON
subclause:
...
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'
That way the right-hand side of the join is filtered on tblDaily.sDate = CAST(GETDATE() AS DATE)
before the join takes place. Consequently, the query will return the expected 37 rows from tblReps
complemented either with matching data from tblDaily
or with nulls.
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
add a comment
|
First of all, the correct type of join to use in this case is a left join:
...
FROM
[tblRepresentatives] AS tblReps
LEFT OUTER JOIN
tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode
...
In your specific case, you could still use FULL
because this condition in WHERE
would turn it into a left join anyway:
tblReps.[sActive] = 'True'
But it is better to express the intent accurately.
The same effect that turns your full join into a left join is actually responsible for the missing 37th row that you expected. More specifically, this other WHERE
condition:
tblDaily.sDate = CAST(GETDATE() AS DATE)
transforms your join further into an inner join. That is why the 37th row is missing from the output.
The reason for that happening is this. The FROM
clause returns a null in tblDaily.sDate
for the unmatched row. Because the WHERE
clause logically executes after the FROM
, the above-mentioned predicate excludes the unmatched row, since NULL = CAST(GETDATE() AS DATE)
does not evaluate to True.
What you need to do instead is move the sDate
condition to the ON
subclause:
...
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'
That way the right-hand side of the join is filtered on tblDaily.sDate = CAST(GETDATE() AS DATE)
before the join takes place. Consequently, the query will return the expected 37 rows from tblReps
complemented either with matching data from tblDaily
or with nulls.
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
add a comment
|
First of all, the correct type of join to use in this case is a left join:
...
FROM
[tblRepresentatives] AS tblReps
LEFT OUTER JOIN
tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode
...
In your specific case, you could still use FULL
because this condition in WHERE
would turn it into a left join anyway:
tblReps.[sActive] = 'True'
But it is better to express the intent accurately.
The same effect that turns your full join into a left join is actually responsible for the missing 37th row that you expected. More specifically, this other WHERE
condition:
tblDaily.sDate = CAST(GETDATE() AS DATE)
transforms your join further into an inner join. That is why the 37th row is missing from the output.
The reason for that happening is this. The FROM
clause returns a null in tblDaily.sDate
for the unmatched row. Because the WHERE
clause logically executes after the FROM
, the above-mentioned predicate excludes the unmatched row, since NULL = CAST(GETDATE() AS DATE)
does not evaluate to True.
What you need to do instead is move the sDate
condition to the ON
subclause:
...
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'
That way the right-hand side of the join is filtered on tblDaily.sDate = CAST(GETDATE() AS DATE)
before the join takes place. Consequently, the query will return the expected 37 rows from tblReps
complemented either with matching data from tblDaily
or with nulls.
First of all, the correct type of join to use in this case is a left join:
...
FROM
[tblRepresentatives] AS tblReps
LEFT OUTER JOIN
tblDailyWorkingTime AS tblDaily ON tblDaily.sRepresentativeCode = tblReps.sCode
...
In your specific case, you could still use FULL
because this condition in WHERE
would turn it into a left join anyway:
tblReps.[sActive] = 'True'
But it is better to express the intent accurately.
The same effect that turns your full join into a left join is actually responsible for the missing 37th row that you expected. More specifically, this other WHERE
condition:
tblDaily.sDate = CAST(GETDATE() AS DATE)
transforms your join further into an inner join. That is why the 37th row is missing from the output.
The reason for that happening is this. The FROM
clause returns a null in tblDaily.sDate
for the unmatched row. Because the WHERE
clause logically executes after the FROM
, the above-mentioned predicate excludes the unmatched row, since NULL = CAST(GETDATE() AS DATE)
does not evaluate to True.
What you need to do instead is move the sDate
condition to the ON
subclause:
...
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'
That way the right-hand side of the join is filtered on tblDaily.sDate = CAST(GETDATE() AS DATE)
before the join takes place. Consequently, the query will return the expected 37 rows from tblReps
complemented either with matching data from tblDaily
or with nulls.
edited May 27 at 16:13
answered May 27 at 13:39
Andriy MAndriy M
17.2k6 gold badges39 silver badges78 bronze badges
17.2k6 gold badges39 silver badges78 bronze badges
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
add a comment
|
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
Thank you, Andriy that explanation was very helpful and makes sense to me. I have tested and I am now getting the expected result.
– Mark Blackburn
May 27 at 14:26
add a comment
|
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f239140%2fjoin-to-obtain-all-the-rows-from-the-first-table-along-with-nulls-from-the-secon%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown