I've got one master
table, which has items stored in multiple levels, parents and childs, and there is a second table which may or may not have additional data. I need to query two levels from my master table and have a left join on my second table, but because of the ordering within my query this will not work.
SELECT something FROM master as parent, master as child
LEFT JOIN second as parentdata ON parent.secondary_id = parentdata.id
LEFT JOIN second as childdata ON child.secondary_id = childdata.id
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID'
The left join only works with the last table in the from clause, so I am only able to make it work for one of the left joins. In the example above none of the left joins will work because the first left join points towards the first table in the from clause, the second one will never work like this.
How can I make this work?
The
JOIN
statements are also part of theFROM
clause, more formally a join_type is used to combine two from_item's into one from_item, multiple one of which can then form a comma-separated list after theFROM
. See http://www.postgresql.org/docs/9.1/static/sql-select.html .So the direct solution to your problem is:
A better option would be to only use
JOIN
's, as it has already been suggested.You can do like this
This kind of query should work - after rewriting with explicit ANSI
JOIN
syntax:The tripping wire here is that an explicit
JOIN
binds before "old style"CROSS JOIN
with comma (,
). I quote the manual here:After rewriting the first, all joins are applied left-to-right (logically - Postgres is free to rearrange tables in the query plan otherwise) and it works.
Just to make my point, this would work, too:
But explicit
JOIN
syntax is generally preferable, as your case illustrates once again.And be aware that multiple (LEFT) JOINs can multiply rows: