繁体   English   中英

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

[英]Ambiguity in an SQL query involving two joins

我有三个表,其结构如下:

results:
id | url_id

foo
id | url_id | url

bar
id | url_id | url

我希望能够在单个查询中选择URL,因为它知道可能在任何一个表中。

我的计划是在两个表上都进行LEFT JOIN ,然后返回诸如IFNULL(foo.url, bar.url) as url

重要的是将结果称为url

但是,由于模棱两可,我无法在WHERE子句中使用相同的url列名称。 这是我的查询和收到的错误消息:

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

选择其他名称下的列并在我的代码中重命名将是相当琐碎的,但是在SQL中这样做会更好。

这是一个SQL提琴: http ://sqlfiddle.com/#!9/32abc6/4

干杯

您不能使用WHERE子句中SELECT子句中声明的别名,因为WHERE发生在SELECT之前。

因此:

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;

要么

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;

您的问题的直接答案是在引用列时使用表别名。 我将其写为一系列的左联接:

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;

该答案假定实际的url匹配可能在任何一个表中,或者如果两者都匹配,则您不介意从foo表中获取版本。

如果同一列名可用于多个表,则您的错误建议使用表别名:

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 = ?;

这将回答Column 'url' in where clause is ambiguous -> Column 'url' in where clause is ambiguous错误,如果这样, JOIN可能与您想要的不一样,然后调整on子句或为JOIN提供其他条件。 但是使用别名来简化查询或编译器的想法是相同的。

如果您想要在哪里可以使用子查询的网址,原因是两个表都具有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

所以你有了

SELECT ..., IFNULL(foo.url, bar.url) AS url
...
WHERE url LIKE ?      *** Error: "url" ambiguous

遗憾的解决方案是使用:

SELECT ..., IFNULL(foo.url, bar.url) AS url
...
WHERE IFNULL(foo.url, bar.url) LIKE ?

它应该不会降低效率。 这是一个人付出的。 也许以下方法会起作用:

SELECT ..., z.url
FROM (SELECT IFNULL(foo.url, bar.url) AS url FROM DUAL AS z)
JOIN ...
WHERE z.url LIKE ?

介绍表别名以消除歧义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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