我有三个表,其结构如下:
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
很重要。
但是,由于含糊不清,我无法在我的url
子句中使用相同的WHERE
列名。这是我的查询和收到的错误消息:
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
欢呼
答案 0 :(得分:2)
您不能使用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
子句中声明的别名,因为WHERE
发生在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;
答案 1 :(得分:1)
您的问题的直接答案是在引用列时使用表别名。我将其写为一系列的左联接:
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
表中获取版本。
答案 2 :(得分:1)
如果相同的列名可用于多个表,则您的错误建议使用表别名:
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
错误,如果如此,JOIN
可能与您想要的不一样,然后调整on
子句或为JOIN
提供其他条件。但是使用别名来简化查询或编译器的想法是相同的。
答案 3 :(得分:1)
如果您想在可以使用子查询的位置使用url,则这两个表都具有url列,但是您只写了一个,因此要么必须在其中使用table.column名称
..., 'DIAPER-BE SURE-M 5''s', ...
答案 4 :(得分:0)
所以你有
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 ?
引入表别名以消除歧义。