Объединение на двух таблицах дает повторяющиеся результаты - PullRequest
0 голосов
/ 25 сентября 2019

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

Basetable:

| ID1 | ID2 | Value |
| a1  |  a2 | val_1 |
| b1  |  b2 | val_2 |
| c1  |  c2 | val_3 |

join Таблица:

| ID1 | ID2 | Join_Value |
|     |  a2 | join_val_1 |
| b1  |     | join_val_2 |
| c1  |  c2 | join_val_3 |

То, что я пробовал, было так:

select base.id1, base.id2, Value, isnull(j1.Join_value,j2.Join_value) Join_Value from base
left join Join j1 on j1.id1 = base.id1
left join Join j2 on j2.id2 = base.id2

Результат таков:

| ID1 | ID2 | Value | Join_Value |
| a1  |  a2 | val_1 | join_val_1 |
| b1  |  b2 | val_2 | join_val_2 |
| c1  |  c2 | val_3 | join_val_3 |
| c1  |  c2 | val_3 | join_val_3 |

То, что я хочу, это:

| ID1 | ID2 | Value | Join_Value |
| a1  |  a2 | val_1 | join_val_1 |
| b1  |  b2 | val_2 | join_val_2 |
| c1  |  c2 | val_3 | join_val_3 |

Надеюсь, я разъяснил свою проблему.

Ответы [ 4 ]

0 голосов
/ 25 сентября 2019

Во-первых, ваша версия делает именно то, что вы хотите. Здесь - это дБ <> скрипка.

Во-вторых, для большего контроля над соответствием можно использовать боковое соединение.Это позволяет вам выбрать только одну подходящую строку - скажем ту, где совпадают оба идентификатора:

select b.id1, b.id2, b.value, jt.join_value
from base b cross apply
     (select top (1) jt.*
      from jointable jt
      where b.id1 = jt.id1 or
            b.id2 = jt.id2
      order by (case when b.id1 = jt.id1 then 1 else 0 end) +
               (case when b.id2 = jt.id2 then 1 else 0 end) desc
     ) jt ;
0 голосов
/ 25 сентября 2019

Вам не нужно присоединяться к одному столу дважды.Просто укажите условие в ON

select  b.ID1, b.ID2, b.[Value], j.Join_Value
from    [base] b
        inner join [join] j on  b.ID1   = j.ID1
                            or  (
                                       j.ID1    = '' 
                                and    b.ID2    = j.ID2
                                )
0 голосов
/ 25 сентября 2019

Попробуйте:

select  *
from base b 
join [join] j on b.id1 = j.id1 or b.id2 = j.id2
0 голосов
/ 25 сентября 2019

Вы получите двойные строки для строк c1 и c2, поскольку они совпадают на обоих ваших Join объединениях таблиц (j1 и j2).

Быстрое решение заключается в добавлении DISTINCT к вашему запросу:

select DISTINCT base.id1, base.id2, Value, isnull(j1.Join_value,j2.Join_value) Join_Value 
from base
left join Join j1 on j1.id1 = base.id1
left join Join j2 on j2.id2 = base.id2

Лучшим решением в зависимости от вашей СУБД является использование оконной функции:

select id1, id2, Value, Join_Value
FROM (
  select base.id1, base.id2, Value, isnull(j1.Join_value,j2.Join_value) Join_Value,
    ROW_NUMBER() OVER(
      PARTITION BY base.id1, base.id2 -- Group rows based on (id1, id2) combination
      ORDER BY j1.id1 -- If more than one row, give priority to row with "id1" value
    ) AS RowNum
  from base
  left join Join j1 on j1.id1 = base.id1
  left join Join j2 on j2.id2 = base.id2
) src
WHERE RowNum = 1 -- Only return one row

Это гарантирует, что вы всегда будете иметь максимум один ряд на комбинацию (id1, id2).

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