【问题标题】:How to join 2 tables without value duplication in PostgreSql如何在 PostgreSql 中加入 2 个不重复值的表
【发布时间】:2019-01-06 18:28:41
【问题描述】:

我正在使用以下方法连接两个表:

select table1.date, table1.item, table1.qty, table2.anotherQty 
from table1
INNER JOIN table2
on table1.date = table2.date

table1

date   | item   | qty
july1  | itemA  | 20
july1  | itemB  | 30
july2  | itemA  | 20

table2

date   | anotherQty
july1  | 200
july2  | 300

预期结果应该是:

date   | item  | qty | anotherQty
july1  | itemA | 20  | 200
july1  | itemB | 30  | null or 0
july2  | itemA | 20  | 300

这样当我 sum(anotherQty) 时,它将只有 500,而不是:

date   | item  | qty | anotherQty
july1  | itemA | 20  | 200
july1  | itemB | 30  | 200
july2  | itemA | 20  | 300

即 200+200+300 = 700

【问题讨论】:

  • 真正最好的办法是在加入之前在原始表中对anotherQty 求和。
  • 两个表之间唯一的关联是日期列。那么,为什么您会期望“200”出现在带有“itemA”的行上呢?为什么不是“itemB”或任何其他“july1”记录?

标签: postgresql duplicates jointable


【解决方案1】:

SQL DEMO

WITH T1 as (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY "date" ORDER BY "item") as rn
  FROM Table1
), T2 as (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY "date" ORDER BY "anotherQty") as rn
  FROM Table2
)
SELECT *
FROM t1
LEFT JOIN t2
       ON t1."date" = t2."date"
      AND t1.rn = t2.rn

输出

过滤您想要的列,并根据需要更改顺序。

|  date |  item | qty | rn |   date | anotherQty |     rn |
|-------|-------|-----|----|--------|------------|--------|
| july1 | itemA |  20 |  1 |  july1 |        200 |      1 |
| july1 | itemB |  30 |  2 | (null) |     (null) | (null) |
| july2 | itemA |  20 |  1 |  july2 |        300 |      1 |

【讨论】:

    【解决方案2】:

    尝试以下代码,但要知道,只要行间的 qty 值不同,您仍然会得到 'anotherQty' 字段分解为不同的值:

    select 
        table1.date, 
        table1.item, 
        table1.qty, 
        SUM(table2.anotherQty)
    from table1
    INNER JOIN table2
        on table1.date = table2.date
    GROUP BY
        table1.item, 
        table1.qty,
        table1.date
    

    如果您需要它始终汇总到每个项目/日期的一行,那么您还需要将 SUM() 添加到 table1.qty。或者,您可以为所需的每个数量运行一个公用表表达式(WITH() 语句),在公用表表达式中对它们求和,然后将表达式重新连接到最终的 SELECT 语句中。

    编辑:

    根据@Juan Carlos Oropeza 的评论,我不确定是否有办法在查询中包含 table1.date 时获得 500 的总和值,因为您必须按日期对输出进行分组将导致聚合拆分为不同的行。以下查询将以牺牲显示日期为代价获得另一个数量的总和:

    select  
        table1.item, 
        SUM(table1.qty), 
        SUM(table2.anotherQty)
    from table1
    INNER JOIN table2
        on table1.date = table2.date
    GROUP BY
        table1.item 
    

    如果您需要保留日期,您可以使用 WINDOW 函数来显示总和,但请注意,这实际上是在执行运行求和,并且可能会丢弃您在此查询输出上执行的任何后续求和在后处理方面:

    select  
        table1.item,
        table1.date,
        SUM(table1.qty), 
        SUM(table2.anotherQty) OVER (Partition By table1.item) 
    from table1
    INNER JOIN table2
        on table1.date = table2.date
    GROUP BY
        table1.item,
        table1.date,
        table2.anotherQty
    

    【讨论】:

    • 你得到相同的结果 OP 不想要 sqlfiddle.com/#!17/beeef/1
    • 啊,是的,这是因为日期列。如果 OP 想要包含日期,我不确定是否有办法让它工作,而不是使用可能会抛弃他们需要如何使用数据的窗口函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多