简体   繁体   English

涉及两个联接的SQL查询中的歧义

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM