【问题标题】:PostgreSQL : Removing duplicates of LEFT OUTER JOIN on 3 tablesPostgreSQL:删除 3 个表上 LEFT OUTER JOIN 的重复项
【发布时间】:2020-08-04 14:00:22
【问题描述】:

我是数据库的初学者。 如果我有这个记录:

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 并不真正关心第一个 tbl 上的哪个记录与另一个匹配的非重复记录?像这样:

|-----------|-----------|-----------|
|  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     |
|-----------|-----------|-----------|

【问题讨论】:

    标签: sql database postgresql join outer-join


    【解决方案1】:

    一种简单的方法使用聚合:

    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       |
    

    我不确定您在这方面的要求有多严格,所以我仍然提供该解决方案,因为它是最简单的方法(否则会显着增加查询的复杂性,因为您需要某种递归)。

    【讨论】:

    • 啊,是的,我实际上需要 cola1 / cola2 上的数据来表示它们在表中与 task_id 匹配的真实内容。所以 。 . .
    • @DyaksaHanindito:我不明白你的意思。这些值实际上位于与task_id 匹配的行的表中。
    【解决方案2】:

    您缺少一个连接

    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
    

    【讨论】:

    • 感谢您的回复!但抱歉,这只是删除具有相同数据的行。想象一下,如果每个表中有 3 行。它还会为您带来第一个表上每个数据的两个重复项,这些数据与第二个表上不同的 2 个其他数据配对。
    • 那么你选择这些行的逻辑是什么?好像从上面的例子,你想过滤掉e2.col_a = e.col_a
    猜你喜欢
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 2012-06-21
    • 2014-10-23
    • 2013-03-10
    相关资源
    最近更新 更多