PostgreSQL: удаление дубликатов LEFT OUTER JOIN на 3 таблицах - PullRequest
0 голосов
/ 21 апреля 2020

Я новичок в базе данных. Если у меня есть эта запись:

tbl_task

|-----------|
|  task_id  |
|-----------|
|   1234    |

tbl_item1

|-----------|-----------|
|  task_id  |   col_a   |
|-----------|-----------|
|   1234    |     x     |
|-----------|-----------|
|   1234    |     y     |

tbl_item2

|-----------|-----------|
|  task_id  |   col_a   |
|-----------|-----------|
|   1234    |     x     |
|-----------|-----------|
|   1234    |     y     |

Пока что мой запрос - просто простое левое соединение:

SELECT a.task_id, e.col_a as cola1, e2.col_a as cola2
FROM tbl_task a
LEFT OUTER JOIN tbl_item1 e ON a.task_id = e.task_id
LEFT OUTER JOIN tbl_item2 e2 ON a.task_id = e2.task_id

И он производит повторяющиеся данные, такие как:

|-----------|-----------|-----------|
|  task_id  |   cola1   |   cola2   |
|-----------|-----------|-----------|
|   1234    |     x     |   x       |
|-----------|-----------|-----------|
|   1234    |     x     |   y       |
|-----------|-----------|-----------|
|   1234    |     y     |   x       |
|-----------|-----------|-----------|
|   1234    |     y     |   y       |

Как добиться неповторяющаяся запись, которой или tbl_item1 / tbl_item2 действительно все равно, какая запись в первой таблице соответствует другой? Как это:

|-----------|-----------|-----------|
|  task_id  |   cola1   |   cola2   |
|-----------|-----------|-----------|
|   1234    |     x     |   y       | <------- here cola 2 could be x / y and it doesn't matter
|-----------|-----------|-----------|
|   1234    |     y     |   x       | <------- and here cola2 could be the value other than the data above it.

Любой ответ будет оценен :). Спасибо.

ОБНОВЛЕНИЕ: Также есть возможность других данных, которые заполняют tbl_item1, но не в tbl_item2. Итак, окончательный результат, который мне нужен:

|-----------|-----------|-----------|
|  task_id  |   cola1   |   cola2   |
|-----------|-----------|-----------|
|   1234    |     x     |   x       |
|-----------|-----------|-----------|
|   1234    |     y     |   y       |
|-----------|-----------|-----------|
|   1234    |     z     |  null     |
|-----------|-----------|-----------|

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Вам не хватает одного соединения

SELECT a.task_id, e.col_a as cola1, e2.col_a as cola2
FROM tbl_task a
LEFT OUTER JOIN tbl_item1 e ON a.task_id = e.task_id
LEFT OUTER JOIN tbl_item2 e2 ON a.task_id = e2.task_id AND e2.col_a <> e.col_a
0 голосов
/ 21 апреля 2020

Один простой метод использует агрегирование:

SELECT a.task_id, e.col_a as cola1, MIN(e2.col_a) as cola2
FROM tbl_task a
LEFT OUTER JOIN tbl_item1 e ON a.task_id = e.task_id
LEFT OUTER JOIN tbl_item2 e2 ON a.task_id = e2.task_id
GROUP BY a.task_id, e.col_a as cola1

Обратите внимание, что это не гарантирует уникальность записей в cola2; как правило, для ваших образцов данных вы получите:

|  task_id  |   cola1   |   cola2   |
|-----------|-----------|-----------|
|   1234    |     x     |   x       | 
|   1234    |     y     |   x       |

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

...