Reputation: 2063
I have a SQL database that contains geographic information. This database has three tables:
PostalCode
----------
Code (char(10))
StateID (uniqueidentifier)
State
-----
ID (uniqueidentifier)
Name (nvarchar(max))
CountryID (uniqueidentifier)
Country
-------
ID (uniqueidentifier)
Name
The relationship is: A country has states. States have postal codes. I'm trying to create a query where I can find all of the states in the country where a specific postal code belongs. Currently, I'm trying the following:
SELECT
s.*
FROM
[PostalCode] p,
[State] s,
[Country] c
WHERE
p.[Zip]='90028' AND
p.[StateID]=s.[ID] AND
s.[CountryID]=c.[ID]
Unfortunately, this result returns 1 record (The State record associated with California). However, in reality, I need it to return 50 records (one for each state in the united states). How do I modify this query to do this?
Thank you
Upvotes: 2
Views: 98
Reputation: 247870
You are using an INNER JOIN
, you need to change your syntax to a LEFT JOIN
:
SELECT s.*
FROM [State] s
LEFT JOIN [PostalCode] p
ON p.[StateID]=s.[ID]
AND p.[Zip]='90028'
LEFT JOIN [Country] c
ON s.[CountryID]=c.[ID]
You will notice that I changed to use ANSI JOIN
syntax instead of the joining the tables with the commas and the WHERE
clause.
A LEFT JOIN
will return all rows from the state
table even if there are not matching rows in the other tables.
If you want to return all states in a country where the postal code is equal to a specific code, then you can use:
select s.*
from state s
inner join
(
SELECT s.countryid
FROM [State] s
INNER JOIN [PostalCode] p
ON p.[StateID]=s.[ID]
INNER JOIN [Country] c
ON s.[CountryID]=c.[ID]
WHERE p.[Zip]='90028'
) c
on s.countryid = c.countryid;
Or you can use:
select s1.*
from state s1
where exists (select s2.countryid
from state s2
inner join country c
on s2.countryid = c.id
inner join postalcode p
on s2.id = p.stateid
where p.zip = 90028
and s1.countryid = s2.countryid)
Upvotes: 3