Click here to Skip to main content
15,890,690 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
we have 2 tables: TblState, TblCity. Table TblState have StateID, State column. Table TblCity have StateID, CityID, City column. Now my question is:

I want to get those state which are not used in TblCity using joins.

What I have tried:

Select TblState.StateID, TblState.State from TblState where TblState.StateID NOT IN (Select StateID from TblCity)

This working fine. but i want this result using joins. i tried following, but not getting proper result.

Select TblState.StateID, TblState.State from TblState Inner Join TblCity ON TblState.StateID <> TblCity.StateID
Posted
Updated 18-Mar-19 6:04am
Comments
Richard Deeming 21-Mar-19 12:35pm    
Visual Representation of SQL Joins[^]

Your INNER JOIN code will produce a result that joins every state to every city that isn't in that state, which is obviously not what you want.

If it's working fine, why do you want to change it?
This is one of those cases where leaving alone is better, as the LEFT JOIN version of this batch is about 4% slower than the NOT IN you are currently using.

I set up some #Temp tables for this to test these two head-2-head, and reviewed the Actual Execution Plans to find that the comparison is 49/51 in favor of the first statement
SQL
SELECT StateID, [Name]
FROM   #tblState
WHERE  StateID NOT IN ( SELECT c.StateID FROM #tblCity c )

SELECT    s.StateID, s.[Name]
FROM      #tblState s
LEFT JOIN #tblCity  c ON s.StateID = c.StateID
WHERE     c.StateID IS NULL

I did also test utilizing the EXCEPT operator, and found this to be about 50% slower than either the JOIN or IN variants above it (split was 28/29/43)
SQL
SELECT s.StateID  FROM #tblState s
  EXCEPT
SELECT c.StateID  FROM #tblCity c
Please note that this will only return the StateID and not the actual StateName. So this would either need to be in an IN statement or JOINed. Either will further reduce performance. Added onto the previous 3 queries the Execution Plan splits become 17-17-26-41
SQL
SELECT StateID, [Name]
FROM   #tblState
WHERE  StateID IN (
         SELECT s.StateID  FROM #tblState s
           EXCEPT
         SELECT c.StateID  FROM #tblCity c
)

Now these are on tables without Primary Keys. I did add them in as well as an Index on the StateID column in the #City table. This sped things up considerable. JOIN vs IN vs EXCEPT changes the Actual Execution Plans to be virtually identical: 33/34/33.
With an IN added onto the EXCEPT query the split is 22/22/22/34.
 
Share this answer
 
v2
Use a LEFT OUTER JOIN or a LEFT JOIN, and check for NULLS - those are the rows you want.
SQL LEFT JOIN vs LEFT OUTER JOIN | Examples[^] but you'd probably be better off with an EXCEPT instead: EXCEPT and INTERSECT (Transact-SQL) - SQL Server | Microsoft Docs[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900