0

I just uploaded my site to Heroku however I got an error in one of my controllers. Apparently I have a syntax error with my postgres code. This works in sqlite3 but when I converted it to postgres a syntax error occurred.

   @cars=Car.find_by_sql("SELECT cars.*, CASE WHEN EXISTS (SELECT book_cars.* FROM book_cars WHERE book_cars.car_id=cars.id AND book='t') THEN 'TRUE' ELSE 'FALSE' END  AS 'is_book' FROM cars WHERE is_book='FALSE'")

Any ideas as to what caused the error? The error code:

PG::SyntaxError: ERROR:  syntax error at or near "'is_book'"
6
  • Try changing 'is_book' to is_book (without the '). Commented Jul 18, 2017 at 15:28
  • I tried doing that then the error became: PG::UndefinedColumn: ERROR: column "is_book" does not exist Commented Jul 18, 2017 at 15:30
  • And are you sure that the column is_book does exist? Commented Jul 18, 2017 at 15:34
  • The column book exists. (t.boolean "book") It works in sqlite3 in my development stage. The error occurs in postgres in my production stage. Commented Jul 18, 2017 at 15:36
  • Just to be clear, the column's name is book or is_book? if you run on your postgres db -> select is_book from YourTable, runs ok? Commented Jul 18, 2017 at 15:40

1 Answer 1

1

Try simple:

SELECT *, 'FALSE' As is_book
FROM cars c
WHERE NOT EXISTS (
   SELECT * FROM book_cars b
   WHERE b.car_id=c.id AND book = 't'
)

you can also use a subquery:

SELECT *
FROM (
   SELECT cars.*, 
          CASE WHEN EXISTS (
              SELECT book_cars.* FROM book_cars 
              WHERE book_cars.car_id=cars.id AND book='t') 
          THEN 'TRUE' ELSE 'FALSE' END  AS is_book
   FROM cars 
) x
WHERE is_book='FALSE';

EDIT


The problem in your query is in WHERE clause in the last line below:

SELECT cars.*, 
       CASE WHEN EXISTS (
            SELECT book_cars.* FROM book_cars 
            WHERE book_cars.car_id=cars.id AND book='t') 
       THEN 'TRUE' ELSE 'FALSE' END  AS 'is_book' 
FROM cars 
WHERE is_book='FALSE';

In standard SQL WHERE clause doesn't see any expression (or "column") declared in the SELECT clause, it can only see columns from tables in the FROM clause.
is_book column is declared in the SELECT clause, so WHERE cannot see it.
If you use a subquery, like:

SELECT *
FROM ( --- subquery
   SELECT some_expression AS new_column
   FROM ....
) x
WHERE new_column = 111

then the outer query sees that new column.

You can also use HAVING clause:

SELECT cars.*, 
       CASE WHEN EXISTS (
            SELECT book_cars.* FROM book_cars 
            WHERE book_cars.car_id=cars.id AND book='t') 
       THEN 'TRUE' ELSE 'FALSE' END  AS 'is_book' 
FROM cars 
HAVING is_book='FALSE';

because HAVING, in contrast to WHERE, does see columns declared at SELECT level.

Sign up to request clarification or add additional context in comments.

2 Comments

This worked thank you very much. If I may ask, what was the problem with my query? I couldn't find what was wrong with it. It worked in Sqlite3.
I've edited the answer, appended an explanation why WHERE doesn't see columns from SELECT

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.