Неоднозначность в запросе SQL, включающем два соединения - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть три таблицы, которые структурированы следующим образом:

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 Fiddle: http://sqlfiddle.com/#!9/32abc6/4

Cheers

Ответы [ 5 ]

0 голосов
/ 20 сентября 2018

Итак, у вас есть

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 ?

Введение псевдонима таблицы для устранения неоднозначности.

0 голосов
/ 20 сентября 2018

Вы не можете использовать псевдоним, объявленный в предложении 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;

или

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;
0 голосов
/ 20 сентября 2018

Ваша ошибка предлагает использовать псевдоним таблицы, если одно и то же имя столбца доступно для нескольких таблиц:

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 s может отличаться от того, что вы хотитеесли это так, то измените предложение on или предоставьте еще одно условие с помощью JOIN.Но идея в том, чтобы использовать псевдоним, чтобы было проще понять запрос или компилятор.

0 голосов
/ 20 сентября 2018

, если вы хотите использовать URL для того, где вы можете использовать подзапрос, потому что в обеих таблицах есть столбец 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
0 голосов
/ 20 сентября 2018

Прямой ответ на ваш вопрос - использовать псевдонимы таблиц при обращении к столбцам.Я бы написал это как серию левых объединений:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...