Соединение в коалессе - PullRequest
0 голосов
/ 22 апреля 2019

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

Что-то вроде:

T1:
session, ID, path
1001, 1, homepage
1001, NULL, about


T2:
ID, path, type
1, homepage, A
2, about, Z

С желаемым результатом:

session, ID, path, type
1001, 1, homepage, A
1001, 2, about, Z

Я пробовал это с:

select * from t1 inner join t2 
on (t1.id = t2.id) or (t1.path = t2.path)

Ноэто приводит к неожиданным дубликатам.Я хочу сделать что-то вроде

select * from t1 inner join t2
on coalesce(t1.id, t1.path) = t2.id

Но это не будет работать правильно, поскольку путь не будет сопоставлен с идентификатором в другой таблице.

Есть какие-нибудь мысли или предложения?

Ответы [ 3 ]

1 голос
/ 22 апреля 2019

Вы хотите значение по умолчанию.Вот один метод, который использует два left join s:

select t2.*, coalesce(t1.path, t1d.path) as path
from t2 left join
     t1 
     on t1.id = t2.id left join
     t1 t1d
     on t1d.id is null;
0 голосов
/ 23 апреля 2019

Лучшее, что я могу придумать:

select
    t1.session,
    coalesce(t1.ID, t2.ID) as ID,
    t2.path,
    t2.type
from
    t1
    inner join t2 on
        (t1.ID = t2.ID) or
        (t1.ID is null and t1.path = t2.path)

Но это все равно может дать нежелательные дубликаты. Я не могу судить о вашем дизайне данных, но если результат дает дубликаты, проблема может быть обнаружена в проблемных (дублирующих и / или неоднозначных) данных в ваших таблицах t1 и / или t2.

Меня также сразу поразило, что поле ID явно может быть пустым в таблице t1. С моей точки зрения, это означало бы, что отношение между таблицами t1 и t2 можно считать «необязательным». В противном случае было бы лучше определить поле ID в таблице t1 как обязательное значение.

0 голосов
/ 22 апреля 2019

Ниже приведен пример для BigQuery Standard SQL

#standardSQL
WITH `project.dataset.table1` AS (
  SELECT 1001 session, 1 id, 'homepage' path UNION ALL
  SELECT 1001, NULL, 'about'
), `project.dataset.table2` AS (
  SELECT 1 id, 'homepage' path, 'A' type UNION ALL
  SELECT 2, 'about', 'Z' 
)
SELECT 
  session,
  IFNULL(t1.id, t2.id) id, 
  IFNULL(t1.path, t2.path) path, 
  type
FROM `project.dataset.table1` t1
JOIN `project.dataset.table2` t2
ON (t1.id = t2.id) OR (t1.path = t2.path)

с выводом

Row session id  path        type     
1   1001    1   homepage    A    
2   1001    2   about       Z      

Я понял, что вы можете присоединиться на основе ТОЛЬКО столбца path, если один или оба id имеет значение NULLВ этом случае ваше предложение ON должно быть таким, как показано ниже

ON t1.id = t2.id 
OR (
  (t1.id IS NULL OR t2.id IS NULL) 
  AND t1.path = t2.path
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...