Reputation: 24679
QUERY #1
SELECT
dbo.CLIENT.CLIENT_ID, dbo.CLIENT.GOC, dbo.SALES_UW_REGION.SALES_UNDERWRITING
FROM dbo.CLIENT LEFT OUTER JOIN
dbo.SALES_UW_REGION ON dbo.CLIENT.GOC = dbo.SALES_UW_REGION.GOC
WHERE (dbo.CLIENT.CLIENT_ID = 23721)
CLIENT_ID, GOC, SALES_UNDERWRITING
23721 332 Underwriting
23721 332 Sales
I can understand why this would return only one row, the reason being that despite the LEFT outer join which ensures both CLIENT records are returned even if they are unmatched, the FILTER is applied AFTER the join, so the resultset only has one row.
Query #2
SELECT
dbo.CLIENT.CLIENT_ID, dbo.CLIENT.GOC, dbo.SALES_UW_REGION.SALES_UNDERWRITING
FROM dbo.CLIENT LEFT OUTER JOIN
dbo.SALES_UW_REGION ON dbo.CLIENT.GOC = dbo.SALES_UW_REGION.GOC
WHERE (dbo.CLIENT.CLIENT_ID = 23721)
and SALES_UW_REGION.SALES_UNDERWRITING = 'Sales '
CLIENT_ID GOC SALES_UNDERWRITING
23721 332 Sales
However, if I move the 'SALES' filter to the JOIN clause, I was susprised to see that still one row is returned.
Query #3
SELECT
dbo.CLIENT.CLIENT_ID, dbo.CLIENT.GOC, dbo.SALES_UW_REGION.SALES_UNDERWRITING
FROM dbo.CLIENT LEFT OUTER JOIN
dbo.SALES_UW_REGION ON dbo.CLIENT.GOC = dbo.SALES_UW_REGION.GOC
and SALES_UW_REGION.SALES_UNDERWRITING = 'Sales '
WHERE (dbo.CLIENT.CLIENT_ID = 23721)
CLIENT_ID GOC SALES_UNDERWRITING
23721 332 Sales
I expected that since it was part of the JOIN clause and the join was a LEFT OUTER, that I would have gotten 2 rows. In general, if the JOIN condition which involves an equality match on two columns, one from the LEFT table and one from teh RIGHT table is not met, in a LEFT OUTER JOIN the LEFT table would be returned with NULL values for values selected from the RIGHT. Why should it be any different if we are matching a value from the RIGHT table to a literal? Shouldn't the row from teh LEFT table still be returned?
Man, I thought this was basic stuff that I had down....
Here's what you need to recreate what I did:
CREATE TABLE [dbo].[CLIENT](
[CLIENT_ID] [bigint] NOT NULL,
[GOC] [char](3) NULL
)
go
CREATE TABLE [dbo].[SALES_UW_REGION](
[GOC] [char](3) NOT NULL,
[SALES_UNDERWRITING] [varchar](12) NULL
)
go
INSERT INTO [dbo].[CLIENT]([CLIENT_ID], [GOC])
SELECT 23721, N'332'
go
INSERT INTO [dbo].[SALES_UW_REGION]([GOC], [SALES_UNDERWRITING])
SELECT N'332', N'Underwriting' UNION ALL
SELECT N'332', N'Sales'
go
Upvotes: 1
Views: 215
Reputation: 415735
I think your confusion involves a misunderstanding of the first result set:
CLIENT_ID, GOC, SALES_UNDERWRITING 23721 332 Underwriting 23721 332 Sales
Though there are two rows in this result set, the results represent data from only one row in the Client table. The join condition allowed the single row from the Client table to match two rows in the Sales_UW_Region table, and so the data for that row from the Client table is duplicated in the result set. There is only one Client record here in the first place, evidenced by the fact that there is only one Client_ID, but the data for the record is shown twice: once for each matching record in Sales_UW_Region.
Later, when you include the and SALES_UW_REGION.SALES_UNDERWRITING = 'Sales '
condition as part of the join's ON
clause, the original single record in the Client table only matches one record from the Sales_UW_Region table. The data for the row no longer needs to be duplicated, and so only one row is returned.
Upvotes: 2
Reputation: 34774
You have one row in your CLIENT
table for CLIENT_ID = 23721
.
You're left joining the other table which has multiple rows for CLIENT_ID = 23721
(when joined with criteria in your first query), but when the joining criteria is altered it excludes one of those rows from the RIGHT
table.
You're getting all records from your LEFT
table regardless of whether they join to records in the RIGHT
table, just as expected.
Upvotes: 3
Reputation: 34563
Your understanding is correct. If the filter is within the JOIN's ON clause, it will not remove rows from the first table.
I think you need to look elsewhere for your problem... Do you really mean to have a trailing space in your 'Sales '
constant?
Here's a JSFiddle to test this: http://sqlfiddle.com/#!2/bfe32/3/0
Upvotes: 0