I have three tables that are structured as follows:
results:
id | url_id
foo
id | url_id | url
bar
id | url_id | url
I want to be able to select the URL in a single query knowing that it could be in either table.
My plan was to do a LEFT JOIN
on both of the tables and then return something like IFNULL(foo.url, bar.url) as url
.
It is important that the result is called url
.
However, I cannot use this same url
column name in my WHERE
clause because of the ambiguity. Here is my query and the error message I get:
SELECT r.id,
COALESCE(foo.url, bar.url) as url
FROM results r
LEFT JOIN foo USING (url_id)
LEFT JOIN bar USING (url_id)
WHERE url IS NOT NULL;
Column 'url' in where clause is ambiguous
It would be fairly trivial to select the column under a different name and rename it in my code, but it would be nicer to do it in SQL.
Here is an SQL Fiddle: http://sqlfiddle.com/#!9/32abc6/4
Cheers
You cannot use an alias name declared in the SELECT
clause in your WHERE
clause, because WHERE
happens before SELECT
.
Hence:
SELECT r.id, COALESCE(foo.url, bar.url) as url
FROM results r
LEFT JOIN foo USING (url_id)
LEFT JOIN bar USING (url_id)
WHERE COALESCE(foo.url, bar.url) IS NOT NULL;
or
SELECT r.id, COALESCE(foo.url, bar.url) as url
FROM results r
LEFT JOIN foo USING (url_id)
LEFT JOIN bar USING (url_id)
WHERE foo.url IS NOT NULL OR bar.url IS NOT NULL;
The direct answer to your question is to use table aliases when referring to columns. I would write this as a series of left joins:
SELECT
r.id,
r.url_id,
COALESCE(f.url, b.url) AS url
FROM results r
LEFT JOIN foo f
ON r.url_id = f.url_id
LEFT JOIN bar b
ON r.url_id = b.url_id;
This answer assumes that the actual url
match could be in either table, or, if it matches to both, then you don't mind taking the version from the foo
table.
Your error suggests to use table alias if same column name available with more than one table :
select f.id, ifnull(b.url, f.url) as url
from foo f left join
bar b
on b.id = f.id
where f.url_id = ?;
This answers your -> Column 'url' in where clause is ambiguous
error, JOIN
s may not same as you want if so then adjust the on
clause or provide one other conditions with JOIN
. But the idea would be same to use alias to make it easier to understand the query or to compiler.
if you want url on where you can use sub-query cause your both table has url column but you make one so either you have to use table.column name in where
select * from
(
SELECT r.id,
COALESCE(foo.url, bar.url) as url
FROM results r
LEFT JOIN foo USING (url_id)
LEFT JOIN bar USING (url_id)
)as t where t.url is NOT NULL
So you have
SELECT ..., IFNULL(foo.url, bar.url) AS url
...
WHERE url LIKE ? *** Error: "url" ambiguous
The sorry solution is to use:
SELECT ..., IFNULL(foo.url, bar.url) AS url
...
WHERE IFNULL(foo.url, bar.url) LIKE ?
It should not be less efficient. It is what one pays. Maybe the following would work:
SELECT ..., z.url
FROM (SELECT IFNULL(foo.url, bar.url) AS url FROM DUAL AS z)
JOIN ...
WHERE z.url LIKE ?
Introducing a table alias for disambiguation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.