【问题标题】:PostgreSQL: Merge records from two tables and calculate the averagePostgreSQL:合并两个表中的记录并计算平均值
【发布时间】:2018-12-24 19:17:50
【问题描述】:

我有两个表,table_1 和 table_2。 我想将 table_1 中的一些记录(具有特定 ID)与 table_2 的一些记录(具有特定 ID)合并。

例如: 我想将 table_1 中 ID 为“AA”的所有记录与 table_2 中 ID 为“HH”的记录合并。但是ID“HH”不应该改变,但是值列Val1和Val2应该通过计算平均值来合并。此外,只有来自 'AA' 和 'HH' 的记录应该合并,它们共享相同的时间戳。 这样table_2在查询执行后就变成了这个样子。

示例如下:

Table_1:
ID |     Timestamp    | Val1 | Val2
-----------------------------------
AA | 2018-14-07 00:00 | 203  | 294
BB | 2018-14-07 00:00 | 193  | 194
CC | 2018-14-07 00:00 | 193  | 136
AA | 2018-14-07 00:15 | 194  | 198
BB | 2018-14-07 00:15 | 124  | 594
CC | 2018-14-07 00:15 | 105  | 110

Table_2:
ID |     Timestamp    | Val1 | Val2
-----------------------------------
HH | 2018-14-07 00:00 | 123  | 311  
GG | 2018-14-07 00:00 | 156  | 202 
HH | 2018-14-07 00:15 | 200  | 502  
HH | 2018-14-07 00:30 | 303  | 198 
PP | 2018-14-07 00:00 | 111  | 123 

Table_2 (after executing the query):
ID |     Timestamp    | Val1 | Val2
-----------------------------------
HH | 2018-14-07 00:00 | 163  | 302  // Val1: (123 + 203)/2 = 163; Val2: (311+294)/2 = 302
GG | 2018-14-07 00:00 | 156  | 202 
HH | 2018-14-07 00:15 | 197  | 350  // Val1: (200 + 194)/2 = 197; Val2: (502+198)/2 = 350
HH | 2018-14-07 00:30 | 303  | 198  // values stay the same because no record with the ID "AA" and the timestamp "2018-14-07 00:30" is available.
PP | 2018-14-07 00:00 | 111  | 123 

如果您有一些问题需要更好地理解,请随时发表评论。我将编辑问题以便更好地理解。

【问题讨论】:

    标签: sql postgresql join


    【解决方案1】:

    查询所需信息,请尝试:

    select T2.ID,
           T2.Timestamp, 
           (T1.Val1 + T2.Val1)/2 Val1,
           (T1.Val2 + T2.Val2)/2 Val2
    from Table2 T2 left join (
        select case ID when 'AA' then 'HH' end ID,
               Timestamp,
               Val1,
               Val2
        from Table1
    ) T1 on T2.ID = T1.ID and T2.Timestamp = T1.Timestamp
    

    为了在Table1的基础上更新Table2,尝试:

    update Table2 as T2 set Val1 = (coalesce(T1.Value1, Val1) + Val1)/2,
                            Val2 = (coalesce(T1.Value2, Val2) + Val2)/2
    from (
        select case ID when 'AA' then 'HH' else ID end ID,
               Timestamp,
               Val1 AS Value1,
               Val2 AS Value2
        from Table1
    ) T1 where T2.ID = T1.ID and T2.Timestamp = T1.Timestamp
    

    【讨论】:

    • 非常感谢!
    • 有一个错误:'select case ID when 'AA' then 'HH' else ID end' 将替换 AA -> HH,但 HH -> HH 也是.. You need 'select case ID当 'AA' 然后 'HH' else null end' 到 HH -> null.
    • @ЕвгенийНоздрев 不,这会导致错误。此外,OP 没有提到这个问题并接受了这个答案 :) 所以查询工作正常 :)
    • @MichałTurczyn 抱歉,我不明白你的意思是什么错误。你能解释一下吗?
    • @ЕвгенийНоздрев 我更新了答案,但这应该由OP提及。你只是在猜测。也许 OP 有更多他想加入的价值观?
    【解决方案2】:

    试试这个

    Select t2.ID, t2.Timestam, 
           Case when t1.Val1 is null Then t2.Val1 ELSE (T1.Val1 + T2.Val1)/2 END Val1,
           Case when t1.Val2 is null Then t2.Val2 ELSE (T1.Val2 + T2.Val2)/2 END Val2 
    from #tbl2 t2
    left join #tbl1 t1
    on t1.Timestam = t2.Timestam
    and t1.ID = 'AA' and t2.ID = 'HH'
    

    【讨论】:

    • 使用 FULL OUTER JOIN 而不是 LEFT:否则如果 tbl2 中没有提供键,则查询将返回 0 行。
    • 什么键? OP 只想要 tbl2 数据
    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    相关资源
    最近更新 更多