Предложение SQL WITH не работает

Я пытаюсь выполнить, казалось бы, простой запрос содержит WITH пункт:

WITH sub AS (SELECT url FROM site WHERE id = 15) 
SELECT * FROM search_result WHERE url = sub.url

Но это не работает. я получил

ОШИБКА: отсутствует запись предложения FROM для таблицы "sub"

В чем дело?

4 ответа

Решение

Табличные выражения должны использоваться как таблицы. Вы пытаетесь использовать значение sub как скаляр.

Попробуйте это (простите, Postgres не мой первый диалект SQL).

WITH sub AS (SELECT url FROM site WHERE id = 15) 
SELECT * FROM sub
INNER JOIN
 search_result 
ON
  sub.url = search_result.url

EDIT, в качестве альтернативы, вы можете просто пропустить предложение WITH и перейти к:-

SELECT * FROM 
  site
INNER JOIN
  search_result 
ON
  site.url = search_result.url
WHERE 
  site.id = 15

Не используйте CTE для этого простого случая. В отличие от ожидаемого, следующий простой запрос без CTE будет немного быстрее:

SELECT r.*
FROM   search_result r
JOIN   site s USING (url)
WHERE  s.id = 15;

Тест с EXPLAIN ANALYZE проверять.

CTEs вводят барьер оптимизации. У них много очень хороших применений, но они не будут делать простые запросы быстрее. Вот поток по pgsql-performance, который дает вам более подробную информацию о том, почему это так.

Вы можете так же легко сделать внутреннее соединение:

SELECT search_result .* 
FROM
    search_result
INNER JOIN
    (SELECT url FROM site WHERE id = 15) as st
ON
    search_result.url = st.url

Это делает фильтрацию так, что вы присоединяетесь к меньшему набору, чем если бы вы делали предложение where за пределами фильтрации. Это может не иметь значения в вашем случае, но это то, что нужно учитывать.

Это не правильный способ использовать CTE:

With sub as (
    SELECT url
    FROM site
    WHERE id = 15
)
SELECT * 
FROM Search_Result SR 
   JOIN sub ON SR.url = sub.Url
Другие вопросы по тегам