簡體   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