Reputation: 1167
I'm trying to execute seemingly simple request contains WITH
clause:
WITH sub AS (SELECT url FROM site WHERE id = 15)
SELECT * FROM search_result WHERE url = sub.url
But it doesn't work. I get
ERROR: missing FROM-clause entry for table "sub"
What's the matter?
Upvotes: 0
Views: 1587
Reputation: 659307
Don't use a CTE at all for this simple case. Unlike you seem to be expecting, the following simple query without a CTE will be slightly faster:
SELECT r.*
FROM search_result r
JOIN site s USING (url)
WHERE s.id = 15;
Test with EXPLAIN ANALYZE
to verify.
CTEs introduce an optimization barrier. They have many very good uses, but they won't make simple queries faster. Here is a thread on pgsql-performance that gives you more details as to why that is.
Upvotes: 1
Reputation: 4539
You can just as easily do an inner join:
SELECT search_result .*
FROM
search_result
INNER JOIN
(SELECT url FROM site WHERE id = 15) as st
ON
search_result.url = st.url
This does the filtering so that you are joining on a smaller set than if you did the where clause outside of the filtering. This may not matter in your case, but it is something to consider.
Upvotes: 0
Reputation: 62861
That's not the correct way to use a CTE:
With sub as (
SELECT url
FROM site
WHERE id = 15
)
SELECT *
FROM Search_Result SR
JOIN sub ON SR.url = sub.Url
Upvotes: 0
Reputation: 10680
Table expressions need to be used like tables. You're trying to use the value of sub as a scalar.
Try this (forgive me, Postgres is not my first SQL dialect).
WITH sub AS (SELECT url FROM site WHERE id = 15)
SELECT * FROM sub
INNER JOIN
search_result
ON
sub.url = search_result.url
EDIT, alternatively, you could just skip the WITH clause and go with:-
SELECT * FROM
site
INNER JOIN
search_result
ON
site.url = search_result.url
WHERE
site.id = 15
Upvotes: 1