代码之家  ›  专栏  ›  技术社区  ›  Bernhard Gratzl

合并具有不同时间戳的表?

  •  0
  • Bernhard Gratzl  · 技术社区  · 8 月前

    我有两张桌子A和B。 (Synology NAS,MariaDB,如果这很重要的话)

    表A每分钟得到一个新记录,表B大约每2分钟得到一条新记录。 由于表B的条目较少,我想将B合并到A中。 问题是:时间戳和列名不匹配!

    现在,我希望有一个查询,将B的时间戳与a的最接近时间戳相匹配,而不创建重复或新行。

    这可以通过一个查询来实现吗?

    例子:

    表A

    日期 abc
    2025-10-17 14:11:14 0
    2025-10-17 14:12:11 0
    2025-10-17 14:13:18 0
    2025-10-17 14:14:15 0
    2025-10-17 14:15:10 0
    ...

    表B

    日期x xyz
    2025-10-17 14:12:26 11
    2025-10-17 14:14:20 22
    ...

    表A已合并

    日期 abc
    2025-10-17 14:11:14 0
    2025-10-17 14:12:11 11
    2025-10-17 14:13:18 0
    2025-10-17 14:14:15 22
    2025-10-17 14:15:10 0
    ...
    3 回复  |  直到 8 月前
        1
  •  0
  •   ValNik    8 月前

    主要问题是如何匹配表A和表B的行。
    我将假设,如果差异小于30秒,则可以认为这些行具有可比性。

    参见示例

    select *
    from TableA a
    left join TableB b 
      on b.date between (a.date- interval 30 second) and (a.date+ interval 30 second)
    
    日期 abc 日期 xyz
    2025-10-17 14:11:14 0 无效的 无效的
    2025-10-17 14:12:11 0 2025-10-17 14:12:26 11
    2025-10-17 14:13:18 0 无效的 无效的
    2025-10-17 14:14:15 0 2025-10-17 14:14:20 22
    2025-10-17 14:15:10 0 无效的 无效的

    实际更新

    Update TableA a,TableB b 
    set a.abc=b.xyz
    where b.date between (a.date- interval 30 second) and (a.date+ interval 30 second)
    
    select * from TableA;
    
    日期 abc
    2025-10-17 14:11:14 0
    2025-10-17 14:12:11 11
    2025-10-17 14:13:18 0
    2025-10-17 14:14:15 22
    2025-10-17 14:15:10 0

    fiddle

        2
  •  0
  •   Nikhil    8 月前

    这需要一个 update 用一个 join :

    UPDATE tableA
    SET tableA.abc= tableB.xyz
    FROM tableA
    JOIN tableB
    ON tableA.date= tableB.date_x;
    
        3
  •  0
  •   p3consulting    8 月前

    您可以使用以下逻辑使用MERGE:

    您必须确定表_b中的一行在表_a中一定有匹配行的时间间隔,例如,在您的示例中,1分钟似乎足够了,但由您来检查数据,然后您可以使用一个查询作为MERGE的来源,在该查询中添加一列,计算表_b.date_x和表_a.date之间差值的绝对值之间的增量排名。限制JOINed的数据量将是DATE/TIMESTAMP列性能+索引的关键之一。

    由于我没有时间用MariaDB语法来做这件事,这里有一个ORACLE中的解决方案:

    merge into table_a dst
    using (
        select date_x, xyz, dat, 
            row_number() over(partition by date_x order by abs((date_x + 0) - (dat + 0))) as rn
        from table_b
        join table_a on dat between date_x - interval '1' minute and date_x + interval '1' minute
    ) src
    on (src.dat = dst.dat and src.rn = 1)
    when matched then
    update set abc = src.xyz ;
    

    为了适应其他SQL方言,你必须检查如何处理DATE或TIMESTAMP算法来计算DATE和DATE_x列之间的差异,以及如何生成JOIN条件中使用的±1分钟间隔(或你最终决定使用的任何时间间隔…),剩下的就是相当标准的SQL。 您还可以处理“不匹配时”的情况,并决定插入新行。