Reputation: 63
I wrote a SQL Query that gets me the names of cities with airports on specific longitudes and latitudes. Is it possible to write this more efficiently (for example without Union or the subqueries I have used)?
SELECT DISTINCT
C.Name
FROM
Cities C
WHERE
C.CityID IN (SELECT A.CityID FROM Airports A
WHERE A.Latitude < 10 AND A.Longtitude < 5
AND C.CityID = A.CityID
UNION ALL
SELECT A.CityID FROM Airports A
WHERE A.Latitude > 50 AND A.Longtitude > 100
AND C.CityID = A.CityID)
The schemas I am using for the cities is:
CREATE TABLE Cities
(
CityID SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL,
UNIQUE Name
);
and the schema for the airports are:
CREATE TABLE Airports
(
IATA CHAR(3) PRIMARY KEY,
Name VARCHAR(256),
CityID INT NOT NULL REFERENCES Cities(CityID),
Latitude DECIMAL NOT NULL,
Longtitude DECIMAL NOT NULL,
Altitude SMALLINT,
UNIQUE (Name, CityID)
);
Upvotes: 1
Views: 62
Reputation: 13179
This is an approach to avoid sub-queries, but I agree that Gordon's approach with EXISTS
is the most efficient query.
SELECT DISTINCT C.Name
FROM Cities C
INNER JOIN Airports A
ON a.CityId = c.CityId
WHERE A.Latitude < 10 AND a.Longtitude < 5
OR a.Latitude > 50 AND a.Longtitude > 100
Upvotes: 2
Reputation: 1269603
Use exists
. For efficiency, I would recommend EXISTS
:
SELECT C.Name
FROM Cities C
WHERE EXISTS (SELECT 1
FROM Airports a
WHERE a.CityId = c.CityId AND
((a.latitude < 10 AND a.longitude < 5) or
(a.latitude > 50 AND a.longitude > 100)
)
);
You want an index on Airports(CityId, latitude, longitude)
for this query.
Upvotes: 2