[英]Ambiguity in an SQL query involving two joins
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. 我希望能够在单个查询中选择URL,因为它知道可能在任何一个表中。
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
. 我的计划是在两个表上都进行
LEFT JOIN
,然后返回诸如IFNULL(foo.url, bar.url) as url
。
It is important that the result is called url
. 重要的是将结果称为
url
。
However, I cannot use this same url
column name in my WHERE
clause because of the ambiguity. 但是,由于模棱两可,我无法在
WHERE
子句中使用相同的url
列名称。 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. 选择其他名称下的列并在我的代码中重命名将是相当琐碎的,但是在SQL中这样做会更好。
Here is an SQL Fiddle: http://sqlfiddle.com/#!9/32abc6/4 这是一个SQL提琴: 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
. 您不能使用
WHERE
子句中SELECT
子句中声明的别名,因为WHERE
发生在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. 该答案假定实际的
url
匹配可能在任何一个表中,或者如果两者都匹配,则您不介意从foo
表中获取版本。
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
. 这将回答
Column 'url' in where clause is ambiguous
-> Column 'url' in where clause is ambiguous
错误,如果这样, JOIN
可能与您想要的不一样,然后调整on
子句或为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 如果您想要在哪里可以使用子查询的网址,原因是两个表都具有url列,但是您只写了一个,因此要么必须在其中使用table.column名称
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. 介绍表别名以消除歧义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.