Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL joins, "there is an entry for table but it cannot be referenced"

I have a SQL query which is failing, giving me the error:

"There is an entry for table but it cannot be referenced from this part of the query"

Going through the query, I need both all 3 tables, but only trips and boats have a matching ID to join on. Test is a shapefile which I need to perform a postGIS function on but it shares no similar column id's to the other two.

 select trips.*
 from trips, test
 inner join boats on boats.id = trips.boat_id
 where st_intersects(trips.geom, test.geom) and
 boats.uid = 44

I think it has something to do with the join statement but I don't really understand what. I'd be very interested in an explanation of what is happening here.

like image 692
hselbie Avatar asked Aug 03 '16 17:08

hselbie


People also ask

Why does natural join not work for all table joining?

The reason NATURAL JOIN won't work here is because both your tables also have a Description column in addition to the PermissionSchemeKey column, so postgres will try to inner join on both columns.

Can we use JOINs in with clause?

You can use the USING clause for a shorthand way of defining join conditions. The USING clause is equivalent to a join condition where each column from the left table is compared to a column with the same name in the right table.

Can you join tables in the where clause?

You join two tables by creating a relationship in the WHERE clause between at least one column from one table and at least one column from another. The join creates a temporary composite table where each pair of rows (one from each table) that satisfies the join condition is linked to form a single row.

What is cross join?

What is a CROSS JOIN in SQL? In SQL, CROSS JOINs are used to combine each row of one table with each row of another table, and return the Cartesian product of the sets of rows from the tables that are joined.


1 Answers

Simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax . . . even if that means writing out CROSS JOIN.

As mentioned in the comments, the right way to write the query is:

 select trips.*
 from trips inner join
      test
      on st_intersects(trips.geom, test.geom) inner join
      boats
      on boats.id = trips.boat_id
 where boats.uid = 44;

However, the question is why this doesn't work:

from trips,
     test inner join
     boats
     on boats.id = trips.boat_id

First, I want to note that the failure of this syntax is better described in the MySQL documentation than in the Postgres documentation:

However, the precedence of the comma operator is less than of INNER JOIN, CROSS JOIN, LEFT JOIN, and so on. If you mix comma joins with the other join types when there is a join condition, an error of the form Unknown column 'col_name' in 'on clause' may occur. Information about dealing with this problem is given later in this section.

I think a simpler way of describing this is that JOIN is an operator that acts on the tables/expressions that are its arguments. The comma separates the arguments. So, the first table simply isn't recognized because the comma "blocks" it.

I think you can get around this using parentheses:

from (trips, test inner) join
     boats
     on boats.id = trips.boat_id

You can definitely get around it using CROSS JOIN:

from trips cross join
     test inner join
     boats
     on boats.id = trips.boat_id

But why bother? There is a correct way to write the query.

like image 175
Gordon Linoff Avatar answered Oct 14 '22 16:10

Gordon Linoff