Как заставить соединиться внутри левой ветки? - PullRequest
2 голосов
/ 19 ноября 2010

Мне нужно ЛЕВОЕ объединение со всей веткой t2 + t3, но если я смогу найти подходящее соединение между t1 и t2, я хочу применить соединение t2 и t3.

   SELECT T1.name,T2.bob,T3.a
     FROM T1
LEFT JOIN T2 ON t1.id = t2.t1_id
     JOIN T3 ON t2.id = T3.t2_id

Что такое синтаксис?

Пример данных:

T1 [id,name]
1 aaa
2 bbb
3 ccc

T2 [id,t1_id,bob]
1,1,777
2,1,888
2,2,999

T3[id,t2_id,a]
1,2,'yeh'

Ожидаемый результат:

 [name] , [a]   , [bob]
  aaa   , 'yeh' , 888
  bbb   , NULL  , NULL
  ccc   , NULL  , NULL

Ответы [ 4 ]

4 голосов
/ 19 ноября 2010

РЕДАКТИРОВАТЬ : Этот запрос возвращает результат, как и ожидалось из ваших данных образца - (Также обратите внимание, что этот запрос взят с помощью ответа Treefrog ниже) -

SELECT t1.[name], t3.a, t2.bob
FROM T2 as t2
JOIN T3 as t3 ON t3.t2_id = t2.id
RIGHT JOIN T1 as t1 ON t1.id = t2.t1_id

Мой старый ответ -

SELECT a
FROM T1 as t1
INNER JOIN T2 as t2 ON t1.id = t2.t1_id
LEFT JOIN T3 as t3 ON t2.id = t3.t2_id
2 голосов
/ 19 ноября 2010
SELECT T1.a
FROM T2
JOIN T3 ON T3.t2_id = T2.id
RIGHT JOIN T1 ON T1.id = T2.t1_id
0 голосов
/ 10 сентября 2012

Это должно работать в MySQL

SELECT * FROM T1
LEFT JOIN (T2
 INNER JOIN T3 ON T2.id=T3.t2_id
) ON T1.id= T2.t1_id
0 голосов
/ 19 ноября 2010

Оба из них дадут вам ваш результат.Не уверен, что будет лучше.

Вложенное заявление:

SELECT [name], NULL AS [a], NULL AS  [bob]
FROM t1
LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
WHERE t3.t2_id IS NULL
AND (SELECT COUNT(*) FROM t1 AS t1b LEFT OUTER JOIN t2 AS t2b ON t1b.id = t2b.t1_id LEFT OUTER JOIN t3 AS t3b ON t2b.id = t3b.t2_id WHERE t1.id = t1b.id AND t3b.a IS NOT NULL) = 0
UNION
SELECT [name], [a], [bob]
FROM t1
LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
WHERE t3.t2_id IS NOT NULL
ORDER BY t1.name

ВРЕМЕННЫЙ СТОЛ:

CREATE TABLE #tmp_Rslt([name] varchar(50), [a] varchar(50), [bob] varchar(50))

--select matches
INSERT INTO #tmp_Rslt
SELECT [name], [a], [bob]
FROM t1
LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
WHERE t3.t2_id IS NOT NULL
ORDER BY t1.name

--select t1's that didn't have matches
INSERT INTO #tmp_Rslt
SELECT [name], NULL AS [a], NULL AS  [bob]
FROM t1
LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
WHERE t3.t2_id IS NULL
AND t1.[name] NOT IN (SELECT DISTINCT [name] FROM #tmp_Rslt)

SELECT *
FROM #tmp_Rslt

--cleanup.
DROP TABLE #tmp_Rslt
...