Как отобразить только записи, где есть совпадение хотя бы в одной из нескольких таблиц? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть несколько таблиц. Я хотел бы присоединиться против. Я хочу видеть записи, в которых есть совпадение хотя бы для одной из этих таблиц

insert into foo values
  (1),
  (2),
  (3),
  (4),
  (5),
  (6),
  (7),
  (8);

insert into a values
  (1),
  (2),
  (3);

insert into b values
  (3),
  (4),
  (5),
  (6);

желаемый вывод:

id      id      id
1       1       (null)
2       2       (null)
3       3       3
4       (null)  4
5       (null)  5
6       (null)  6   

Обычно я бы делал это, используя WHERE EXISTS (например: ниже), но это не поддерживается в SparkSQL. Какой самый эффективный способ добиться этого? Я бы предпочел полагаться на мое объединение, чтобы определить результат, а не фильтровать набор результатов. Кроме того, я не ограничиваюсь использованием SparkSQL, API-интерфейс dataframe также хорош.

select * 
from foo
left join a on foo.id = a.id
left join b on foo.id = b.id
where exists (select 1 from a x where foo.id = x.id)
or exists (select 1 from b x where foo.id = x.id)
;

Ответы [ 4 ]

0 голосов
/ 30 августа 2018

Вот решение с DataFrame API:

val foo = (1 to 8).toDF("id")
val a = Seq(1,2,3).toDF("id")
val b = Seq(3,4,5,6).toDF("id")


foo
.join(a,foo("id")===a("id"),"left")
.join(b,foo("id")===b("id"),"left")
.where(a("id").isNotNull or b("id").isNotNull)
.show()

+---+----+----+
| id|  id|  id|
+---+----+----+
|  1|   1|null|
|  2|   2|null|
|  3|   3|   3|
|  4|null|   4|
|  5|null|   5|
|  6|null|   6|
+---+----+----+
0 голосов
/ 30 августа 2018

Вы рядом:

select * 
from foo left join
     a
     on foo.id = a.id left join
     b
     on foo.id = b.id
where a.id is not null or b.id is not null;
0 голосов
/ 30 августа 2018

Вам нужно FULL OUTER JOIN ИЛИ LEFT JOIN с фильтром:

select f.*, a.*, b.*
from foo f full outer join
     a
     on a.id = f.id full outer join
     b
     b.id = f.id
where a.id is not null or b.id is not null;
0 голосов
/ 30 августа 2018

Вы можете попробовать LEFT JOIN и добавить некоторое условие в where

SELECT * 
FROM foo 
LEFT JOIN a on foo.id  = a.id 
LEFT JOIN b on foo.id  = b.id 
WHERE a.id IS NOT NULL OR  b.id IS NOT NULL
ORDER BY foo.id
...