问题描述:

I have the following query:

query = param.tag_list.join("|")

title = "ts_headline(title, query) AS title"

rank = "ts_rank_cd(tsv, query) AS rank"

Job.select(

[

title, rank, :starts_at, :slug, :job_position_id, :id, :city_id,

:company_office_id

]

).from(

"jobs, to_tsquery('english', '#{query}') AS query"

).where(

"tsv @@ query AND enabled = true"

).with_position.with_city.with_office.order(

"rank DESC, starts_at DESC"

).limit(limit)

The with_* scopes just do an includes on positions, city, office. Not more.

This leads to Arel making a query that produces an error:

ActiveRecord::StatementInvalid - PG::Error: ERROR: invalid reference

to FROM-clause entry for table "jobs" LINE 1: ...ER JOIN

"job_positions" ON "job_positions"."id" = "jobs"."jo...

^ HINT: There is an entry for table "jobs", but it cannot be referenced from

this part of the query.

This is most likely related to the problem of mixing implicit and explicit JOINS. See also this ERROR: invalid reference to FROM-clause

The thing is that I don't know how to rewrite the query with the to_tsquery so that it works?

Muchas gracias in advance for any idea

UPDATE

Here the exact query that is produced by Arel in the end. The error refers to the jobs.job_position_id from the first LEFT OUTER JOIN

SELECT

...

FROM

jobs, to_tsquery('english', 'coffeescript|backbone.js|javascript|node.js') AS query

LEFT OUTER JOIN

"job_positions" ON "job_positions"."id" = "jobs"."job_position_id"

LEFT OUTER JOIN

"cities" ON "cities"."id" = "jobs"."city_id"

LEFT OUTER JOIN

"company_offices" ON "company_offices"."id" = "jobs"."company_office_id"

LEFT OUTER JOIN

"companies" ON "companies"."id" = "company_offices"."company_id"

WHERE

(tsv @@ query AND enabled = true)

ORDER BY

rank DESC, starts_at DESC

LIMIT 9

网友答案:

It's a bit hard to tell where the error is coming from exactly without the SQL you're actually generating, but you're almost certainly referencing jobs in a subquery that is at the same level as jobs in the query tree.

Basically, the construct that won't work is the following:

select ...
from foo, (select ... from bar where bar.x = foo.y) as baz

The easiest fix usually is to alias things accordingly:

select ...
from foo, (select ... from bar, foo as foo2 where bar.x = foo2.y and ...) as baz

See this question here for another example:

SQL subquery questions, "ERROR: invalid reference to FROM-clause entry ..."


In your case, this:

FROM 
    jobs, to_tsquery('english', 'coffeescript|backbone.js|javascript|node.js') AS query 
WHERE 
    (tsv @@ query AND enabled = true) 

Should be:

FROM 
    jobs
WHERE 
    (tsv @@ to_tsquery('english', 'coffeescript|backbone.js|javascript|node.js') AND enabled = true)

This should work too:

FROM 
    ( select to_tsquery('english', 'coffeescript|backbone.js|javascript|node.js') AS query ) q,
    jobs 
WHERE 
    (tsv @@ q.query AND enabled = true) 
相关阅读:
Top