Как условно определить значение ON для JOIN в SQL? - PullRequest
0 голосов
/ 27 сентября 2011

У меня проблема с условным соединением.

Это мой запрос:

SELECT table_b.name
FROM table_a
LEFT JOIN table_b
ON table_a.id = table_b.a_id

Описание моей таблицы_b:

id, a_id, ref_z, name
----------------------
1 | 0   |   1  | James
2 | 0   |   2  | John
3 | 2   |   2  | John. S
4 | 0   |   3  | Martin
5 | 6   |   3  | Martin. M
6 | 2   |   3  | Martin. M. Mr

Допустим, у меня есть параметр @ a_id.

Я хотел бы объединить table_a и table_b ON table_a.id = @a_id, если он существует в 0.

Таким образом, результат предыдущего запроса будет (с @a_id = 2):

James
John. S
Martin. M. Mr

У кого-нибудь есть идея, сообщение в блоге, страница руководства или что-нибудь еще, что может привести меня к правильному запросу?

Спасибо,

Ответы [ 3 ]

1 голос
/ 27 сентября 2011
where a_id = 2 

Ваше объединение может быть сокращено до using (a_id), так как оба столбца имеют одинаковое имя и нет двусмысленности.

on / using не следует путать с вашим предложением предиката (where)

0 голосов
/ 27 сентября 2011

Вы можете попробовать использовать IFNULL с дополнительным выбором?:

SELECT ifnull(table_b.name,(select s.name from table_a sa inner join table_b sb on sa.a_id = sb.a_id where sb.a_id = 0 limit 1)) as name 
FROM table_a
LEFT JOIN table_b
ON table_a.id = table_b.a_id;

Не проверено Боюсь, но надеюсь, что это поможет!

Кроме того - как вы хотите обрабатывать несколько строк сa_id = 0?Вышеприведенное вернет только первый ряд, если есть несколько ...

0 голосов
/ 27 сентября 2011

Если у вас есть только одна таблица, у меня это сработало

DECLARE @t TABLE
(
id int,
a_id int,
ref_z int,
name varchar(50)
)

INSERT INTO @t VALUES (1, 0, 1, 'James'),
(2, 0, 2, 'John'),
(3, 2, 2, 'John. S'),
(4, 0, 3, 'Martin'),
(5, 6, 3, 'Martin. M'),
(6, 2, 3, 'Martin. M. Mr')

DECLARE @a_id int = 2

SELECT COALESCE(table_b.name, (SELECT table_b2.name FROM @t AS table_b2 WHERE table_b2.a_id = 0 ORDER BY table_b2.id LIMIT 1)) AS name
FROM (
SELECT ref_z 
FROM @t AS table_z
GROUP BY ref_z
) AS table_z
LEFT OUTER JOIN @t AS table_b ON table_b.ref_z = table_z.ref_z AND table_b.a_id = @a_id

И результаты:

James
John. S
Martin. M. Mr

Также обратите внимание, что это также будет отображать только одну запись (первую), если есть несколько совпадений для a_id = 0

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