2016-03-04 2 views
3

Я изучаю SQL с помощью PostgreSQL, и я пытаюсь изменить один из запросов с сайта PostgreSQL Tutorial.SQL Альтернатива использованию WHERE в качестве подзапроса

Исходный запрос заключается в следующем:

SELECT film_id, title 
FROM film 
WHERE film_id IN (
    SELECT inventory.film_id 
    FROM rental 
    INNER JOIN inventory ON inventory.inventory_id = rental.inventory_id 
    WHERE return_date BETWEEN '2005-05-29' AND '2005-05-30' 
); 

Это работает, но я хочу, чтобы включить rental.return_date в моем выходе. Я был в состоянии добиться этого, используя следующие изменения, но это ужасно медленно (занимает 46096ms вместо 40мса):

SELECT film_id, title, return_date 
FROM film, rental 
WHERE film_id IN (
    SELECT inventory.film_id 
    FROM rental 
    INNER JOIN inventory ON inventory.inventory_id = rental.inventory_id 
    WHERE return_date BETWEEN '2005-05-29' AND '2005-05-30' 
) 
ORDER BY return_date; 

Я пошарил этот сайт, и я подозреваю, что мне нужно изменить ИНЕК к внутреннему ПРИСОЕДИНЯЙТЕСЬ, но мои попытки все провалились до сих пор. Есть ли простой способ ускорить этот запрос?

+0

Если вы хотите помочь с выполнением вам необходимо обеспечить вывод EXPLAIN ANALYZE, или по крайней мере EXPLAIN. Тем не менее, существует непосредственная проблема в том, что вы добавили другую таблицу в свой ОТ, но не имеете ничего, что связывает ее с любой другой таблицей. Это создает декартово произведение, которое будет возвращать огромное количество строк, если одна из таблиц не имеет крошечного количества строк. –

ответ

5

Вам вообще не нужен подзапрос.

Просто присоединитесь к таблицам в том, что является единственным логическим способом объединения таблиц вообще, а затем заимствует предложение where из предыдущего подзапроса, которое будет использоваться в качестве предложения where для вашего запроса.

SELECT film.film_id, film.title, rental.return_date 
FROM film 
    INNER JOIN inventory ON inventory.film_id = film.film_id 
    INNER JOIN rental ON rental.inventory_id = inventory.inventory_id 
WHERE rental.return_date BETWEEN '2005-05-29' AND '2005-05-30' 
ORDER BY rental.return_date 
+0

Отлично! Кроме того, я могу добавить rent.return_date в заголовок SELECT, чтобы получить дату возврата в выходной таблице. Благодаря! – Drew

+0

Да, извините, я пропустил, что вы тоже искали эту колонку, но это простое дополнение. – nhgrif

0

Просто, чтобы сделать его еще меньше ...

SELECT f.film_id, f.title, r.return_date 
FROM film f 
    INNER JOIN inventory i USING (film_id) 
    INNER JOIN rental r USING (inventory_id) 
WHERE r.return_date BETWEEN '2005-05-29' AND '2005-05-30' 
ORDER BY r.return_date