SQL实现根据时间戳和增量标记IDU获取最新记录和脱IDU标记

需求说明:表中有 id, info, cnt 三个字段,对应的增量表多idu增量标记字段和时间戳字段ctimestamp。增量表中的 id 会有重复,其他字段 info、cnt 会不断更新,idu为增量标记字段,ctimestamp为IDU操作的时间戳。目的时要做到:
1)获取增量表中的时间戳字段(ctimestamp)为最新值对应的记录、进行id去重;
2)将第一步的查询结果进行脱IDU标记和时间戳字段、合并到最终的表中(不带IDU标记和时间戳字段)。

SQL查询根据时间戳字段和id字段获取最新值的记录

-- 表字段说明:id 会有重复,其他字段 info、cnt 会不断更新,idu为增量标记字段,ctimestamp为IDU操作的时间戳,需求是要获取时间戳字段(ctimestamp)为最新值对应的记录:

-- 脱IDU和时间戳以后的最终目的表(不带增量标记和时间戳字段)
drop table if exists test81;

-- 带IDU标记idu字段和时间戳字段ctimestamp,id字段可能存在重复的值的记录
drop table if exists test81_idu;

-- 基于 test81_idu 生成的 D 的记录,id唯一(去重后无重复记录)
drop table if exists test81_tmp2_d;

-- 基于 test81_idu 生成的 I、U 的记录,id唯一(去重后无重复记录)
drop table if exists test81_tmp3_iu;


-- 创建最终目的表、并构部分已有数据
create table test81 (
  id int not null, 
  info varchar(100), 
  cnt int,
  primary key(id));

 insert into test81 (id,info,cnt) values (1, 'aaa', 31);
 insert into test81 (id,info,cnt) values (2, 'bbb', 33);
 insert into test81 (id,info,cnt) values (3, 'ccc', 35);

注意:如果是GBase8a primary key(id)  主键约束无效。 

select * from test81;

查询结果:

+----+------+------+
| id | info | cnt  |
+----+------+------+
|  1 | aaa  |   31 |
|  2 | bbb  |   33 |
|  3 | ccc  |   35 |
+----+------+------+


-- 创建带IDU标记的表,id存在重复多条记录
create table test81_idu (
  id int not null, 
  info varchar(100), 
  cnt int,
  idu varchar(10),
  ctimestamp timestamp);
  
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (1, 'aaa', 31, 'I', '2023-10-27 12:31:31.123456789');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (2, 'bbb', 33, 'I', '2023-10-27 12:33:33.123456789');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (3, 'ccc', 35, 'I', '2023-10-27 12:35:35.123456789');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (1, 'aaa', 50, 'U', '2023-10-27 12:50:50.123456789');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (1, 'aaa', 41, 'U', '2023-10-27 12:41:41.123456789');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (2, NULL, NULL, 'D', '2023-10-27 12:52:52.123456789');
 
 注意:MySQL支持上面9位(精确到纳秒的输入),只是数据库行为实际上丢弃后面3位,只取前面6位,但不会报错,能执行成功。但如果是GBase8a,则不行,只能指定6位:
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (1, 'aaa', 31, 'I', '2023-10-27 12:31:31.123456');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (2, 'bbb', 33, 'I', '2023-10-27 12:33:33.123456');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (3, 'ccc', 35, 'I', '2023-10-27 12:35:35.123456');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (1, 'aaa', 50, 'U', '2023-10-27 12:50:50.123456');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (1, 'aaa', 41, 'U', '2023-10-27 12:41:41.123456');
 insert into test81_idu (id,info,cnt,idu,ctimestamp) values (2, NULL, NULL, 'D', '2023-10-27 12:52:52.123456');


select * from test81_idu;

执行结果:
+----+------+------+------+---------------------+
| id | info | cnt  | idu  | ctimestamp          |
+----+------+------+------+---------------------+
|  1 | aaa  |   31 | I    | 2023-10-27 12:31:31 |
|  2 | bbb  |   33 | I    | 2023-10-27 12:33:33 |
|  3 | ccc  |   35 | I    | 2023-10-27 12:35:35 |
|  1 | aaa  |   50 | U    | 2023-10-27 12:50:50 |
|  1 | aaa  |   41 | U    | 2023-10-27 12:41:41 |
|  2 | NULL | NULL | D    | 2023-10-27 12:52:52 |
+----+------+------+------+---------------------+


表字段说明:id 会有重复,其他字段 info、cnt 会不断更新,idu为增量标记字段,ctimestamp为IDU操作的时间戳,需求是要获取时间戳字段(ctimestamp)为最新值对应的记录:


脱IDU标记合并处理(中间用多个到临时表)


-- 先查询一下根据时间戳字段和id进行处理,对id去重(同一个id的多条重复记录,只取时间戳最新的一条记录)
SELECT a.id,a.info,a.cnt,a.idu FROM test81_idu a,(
SELECT 
id, MAX(ctimestamp)AS time
FROM test81_idu
GROUP BY id
ORDER BY COUNT(*)DESC)b WHERE a.id=b.id and a.ctimestamp=b.time;

执行结果:
+----+------+------+------+
| id | info | cnt  | idu  |
+----+------+------+------+
|  3 | ccc  |   35 | I    |
|  1 | aaa  |   50 | U    |
|  2 | NULL | NULL | D    |
+----+------+------+------+

-- 如果用 INSERT INTO 则需要先创建目标表、如果用 SELECT INTO 则要保证目标表不存在(执行时会创建目标表)
DROP TABLE IF EXISTS test81_tmp2_d;
-- CREATE TABLE IF NOT EXISTS test81_tmp2_d  LIKE test81_idu;

-- 根据id和时间戳查询最新记录、并只显示idu='D'的结果
-- MySQL不支持的方式:
-- SELECT id,info,cnt INTO test81_tmp2_d FROM test81_idu;

-- MySQL能支持的方式:
DROP TABLE IF EXISTS test81_tmp2_d;
CREATE TABLE test81_tmp2_d 
(
SELECT a.id,a.info,a.cnt,a.idu FROM test81_idu a,(
SELECT 
id, MAX(ctimestamp)AS time
FROM test81_idu
GROUP BY id
ORDER BY COUNT(*)DESC)b WHERE a.id=b.id AND a.ctimestamp=b.time AND a.idu='D'
);

-- 查询结果:
select * from test81_tmp2_d;
+----+------+------+------+
| id | info | cnt  | idu  |
+----+------+------+------+
|  2 | NULL | NULL | D    |
+----+------+------+------+


-- 根据id和时间戳查询最新记录、并只显示idu='IU'的结果
-- MySQL能支持的方式
DROP TABLE IF EXISTS test81_tmp3_iu;
CREATE TABLE test81_tmp3_iu 
(
SELECT a.id,a.info,a.cnt,a.idu FROM test81_idu a,(
SELECT 
id, MAX(ctimestamp)AS time
FROM test81_idu
GROUP BY id
ORDER BY COUNT(*)DESC)b WHERE a.id=b.id AND a.ctimestamp=b.time AND (a.idu IN ('I','U'))
);

-- 查询结果:
select * from test81_tmp3_iu;
+----+------+------+------+
| id | info | cnt  | idu  |
+----+------+------+------+
|  3 | ccc  |   35 | I    |
|  1 | aaa  |   50 | U    |
+----+------+------+------+


-- 将'D'的数据从最终目标表删除
DELETE FROM test81 WHERE id in (SELECT DISTINCT id FROM test81_tmp2_d);


-- 'D' 记录删除后,查看目的表数据
select * from test81;
+----+------+------+
| id | info | cnt  |
+----+------+------+
|  1 | aaa  |   31 |
|  3 | ccc  |   35 |
+----+------+------+


-- 将'I'和'U'的数据插入或更新到最终的目标表
-- merge into, 目的表的关联id存在则update、不存在则insert:

-- GBase8a 使用 merge into (MySQL 不支持该语法)
-- merge into test81 t1 using test81_tmp3_iu tmp on t1.id=tmp.id when matched then update set t1.info=tmp.info,t1.cnt=tmp.cnt when not matched then insert(id,info,cnt)values(tmp.id,tmp.info,tmp.cnt);

-- MySQL 使用 insert into (GBase8a 不支持该语法)
INSERT INTO test81(id,info,cnt) SELECT id,info,cnt FROM test81_tmp3_iu ON DUPLICATE KEY UPDATE info=VALUES(info), cnt=VALUES(cnt);


-- 'I'和'U'合并到目的表后,查询结果
select * from test81;
+----+------+------+
| id | info | cnt  |
+----+------+------+
|  1 | aaa  |   50 |
|  3 | ccc  |   35 |
+----+------+------+


到此为止,整个脱IDU表级和时间戳的流程处理完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/127253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车托运使用的场景

在托运车辆时,要仔细的检查车辆的性能,比如电瓶电量是否充足,发动机的性能是否良好,轮胎是否是正常的气压,冬季时需使用防冻液,车内禁止放易燃易爆物品。 托运时还需选择一家好的托运公司,首先要…

NumPy 相关函数

本篇文章介绍了Python中NumPy库的相关函数 np.corrcoef() 函数。 NumPy 中的相关性 相关系数是一个数字值,表示数据集给定特征之间的关系。 相关性可以是正相关,这意味着它们具有直接关系,并且一个特征的增加会导致另一个特征的增加。 负相…

创建ABAP数据库表和ABAP字典对象-创建表01

创建表 创建表在你的Package包中 选择(右键单击)包并从上下文菜单中选择New > Other ABAP Repository Object: 2.输入过滤器文本表>数据库表,然后选择Next。 3.输入一个名称,例如ZTRAINING_XXX(一般是具体的项目描述XXX),然后选择Nex…

当你在浏览器地址栏输入一个URL后,将会发生的事情?个人笔记

客户端 在浏览器输入 URL 回车之后发生了什么(超详细版) - 知乎 (zhihu.com) 大致流程是: URL 解析DNS 查询TCP 连接处理请求接受响应渲染页面 1.URL解析 地址解析: 首先判断你输入是否是一个合法的URL还是一个待搜索的关键…

Mysql数据库学习思路

学习 MySQL(或其他数据库管理系统)需要一系列步骤和资源,以帮助您掌握数据库设计、查询语言(SQL)和数据库管理的基础知识。以下是一些建议的学习步骤: 学习数据库基础知识: 了解什么是数据库、数…

5.5 TCP报文段的首部格式

思维导图: 5.5 TCP报文段的首部格式 基本概念 TCP报文段:包含首部和数据两部分,首部至少20字节。作用:首部字段定义了TCP的功能和行为。长度:首部长度可变,基础首部20字节,可添加选项。 首部…

《算法通关村——缓存机制了解LRU实现》

《算法通关村——缓存机制了解LRU实现》 介绍 LRU是"Least Recently Used"(最近最少使用)的缓存机制,它是一种常用的缓存算法,用于管理缓存中的数据项。LRU缓存机制的基本思想是,当缓存达到其容量限制时&a…

【Tricks】PC端微信输入时,文本出现右对齐情况怎么恢复

应该是摁到某个快捷键,于是光标就变成如下图所示的样子: 如果再输入字符,则字符就会变成下图所示的样子(对齐输入框右侧): 解决办法:ctrl J 解决办法:ctrl J 解决办法&#xff1…

5.2 用户数据报协议UDP

思维导图: 课程笔记:5.2 用户数据报协议UDP 5.2.1 UDP概述 一、UDP基本概念 无连接协议:UDP是一个简单的面向数据报的传输层协议,不需要在数据传输前建立连接,故减少开销和延迟。复用/分用:UDP允许多个应…

window压缩包安装mongodb并注册系统服务

下载解压包 https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.22.zip启动mongod 解压压缩包 至 d:\mongodb目录中,创建目录data、logs。并创建配置文件mongod.conf输入以下配置 dbpath d:\mongodb\data logpath d:\mongodb\logs\mongo.log loga…

我的ChatGPT的几个使用场景

示例一,工作辅助、写函数代码: 这里展示了一个完整的代码,修正,然后最终输出的过程。GPT具备足够丰富的相关的小型代码生成能力,语法能力也足够好。这类应用场景,在我的GPT使用中,能占到65%以上…

PostgreSQL 特殊数据类型UUID PG_LSN

1.UUID类型 UUID(Universally Unique Identifier)用于存储一个UUID。 UUID定义在RFC 4122和ISO/IEC 9834-8:2005中。它是一个128bit的数 字。 [postgrespostgres ~]$ [postgrespostgres ~]$ psql psql (13.9) Type "help" for help.postgre…

数据分析过程中,发现数值缺失,怎么办?

按照数据缺失机制,数据分析过程中,我们可以将其分为以下几类: (1)完全随机缺失(MCAR):所缺失的数据发生的概率既与已观察到的数据无关,也与未观察到的数据无关。 &#x…

Spring Boot 使用断言抛出自定义异常,优化异常处理机制

文章目录 什么是断言?什么是异常?基于断言实现的异常处理机制创建自定义异常类创建全局异常处理器创建自定义断言类创建响应码类创建工具类测试效果 什么是断言? 实际上,断言(Assertion)是在Java 1.4 版本…

docker解决oracle中ORA-12514和ORA-03113问题

ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务; 1、进入docke容器 docker exec -it 容器id bash 2、找到并修改listener.ora文件 查看oracle的位置 命令:cat /etc/profile 这是listener.ora文件的位置 /home/oracle/app/oracl…

【办公软件】C#调用NPOI实现Excel文件的加载、导出功能

文章目录 1. 引言2. 环境准备3. 示例代码4. 结果5. 总结 1. 引言 本文将介绍如何使用C#和NPOI库实现Excel文件的读写操作,并通过加载文件和导出文件的按钮进行封装。NPOI是一个强大的.NET库,可以轻松处理Excel文件。我们将学习如何使用NPOI打开现有的Ex…

JVM虚拟机:你是如何理解Java中的垃圾?

什么是垃圾? 垃圾就是内存中不再被使用到的空间,当一个对象不再被引用后那么久成为垃圾可以回收了,但是线程计算没有引用也可以独立运行,因此线程和对象不同。如果一个对象没有任何一个引用指向它了,那么这个对象就是…

【机器学习】五、贝叶斯分类

我想说:“任何事件都是条件概率。”为什么呢?因为我认为,任何事件的发生都不是完全偶然的,它都会以其他事件的发生为基础。换句话说,条件概率就是在其他事件发生的基础上,某事件发生的概率。 条件概率是朴…

【c++|opencv】二、灰度变换和空间滤波---3.均值滤波

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 均值滤波 1. 均值滤波 #include <iostream> #include <opencv2/opencv.hpp> #include"Salt.h"using namespace cv; using names…