联合查询分组取最新数据
场景: sql分组取最大优化
描述
同事今天遇到一个查询,一次有问题,让我帮忙查看,先上数据,有两张浏览表需要取到用户最新的浏览值数据结构如下
表一
CREATE TABLE `ums_member_read202206` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`member_id` bigint(11) NOT NULL COMMENT '会员id',`product_id` bigint(11) NOT NULL COMMENT '商品id',`member_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '会员名称',`product_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名称',`product_pic` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品图片',`product_sn` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品货号',`product_price_now` decimal(10, 2) NULL DEFAULT NULL COMMENT '商品阅览价格',`create_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '阅览时间',`state` int(11) NULL DEFAULT 0 COMMENT '状态 0/未删除 1/已删除',`last_id` int(11) NOT NULL COMMENT '记录上次浏览id',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '会员阅览记录表' ROW_FORMAT = Compact;-- ----------------------------
-- Records of ums_member_read202206
-- ----------------------------
INSERT INTO `ums_member_read202206` VALUES (3, 17685, 6006, 'PaiTest123', 'Gnarhunters × Nike SB Dunk Low Pro Qs Black Black white', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220518/1652865848704.jpg?wh=750*600', 'DH7756-010', 1000.00, '2022-06-01 04:14:46', 0, 0);
INSERT INTO `ums_member_read202206` VALUES (4, 17685, 6026, 'PaiTest123', 'adidas Kids Yeezy Slide ONYX', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220523/1653293331836.jpg?wh=750*600', 'HQ4115', 0.00, '2022-06-26 05:21:29', 0, 3);
INSERT INTO `ums_member_read202206` VALUES (5, 17698, 2788, 'Li878906', 'adidas Yeezy Slide Pure (GW1934)', 'http://carryme-oss-prod.oss-accelerate.aliyuncs.com/mall/images/20211217/1639718432398.jpg?wh=750*600', 'GW1934', 10000.00, '2022-06-01 10:42:51', 0, 0);
INSERT INTO `ums_member_read202206` VALUES (6, 17698, 2788, 'Li878906', 'adidas Yeezy Slide Pure (GW1934)', 'http://carryme-oss-prod.oss-accelerate.aliyuncs.com/mall/images/20211217/1639718432398.jpg?wh=750*600', 'GW1934', 10000.00, '2022-06-26 11:42:51', 0, 0);
INSERT INTO `ums_member_read202206` VALUES (7, 17698, 6026, 'Li878906', 'adidas Kids Yeezy Slide ONYX', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220523/1653293331836.jpg?wh=750*600', 'HQ4115', 0.00, '2022-06-01 10:55:01', 0, 3);
表二、
CREATE TABLE `ums_member_read202207` (`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`member_id` bigint(11) NOT NULL COMMENT '会员id',`product_id` bigint(11) NOT NULL COMMENT '商品id',`member_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '会员名称',`product_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名称',`product_pic` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品图片',`product_sn` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品货号',`product_price_now` decimal(10, 2) NULL DEFAULT NULL COMMENT '商品阅览价格',`create_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '阅览时间',`state` int(11) NULL DEFAULT 0 COMMENT '状态 0/未删除 1/已删除',`last_id` int(11) NOT NULL COMMENT '记录上次浏览id',`last_id_state` tinyint(2) NOT NULL DEFAULT 0 COMMENT '是否为上月浏览ID(0:否 1:是)',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 672 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '会员阅览记录表' ROW_FORMAT = Compact;-- ----------------------------
-- Records of ums_member_read202207
-- ----------------------------
INSERT INTO `ums_member_read202207` VALUES (665, 17685, 6006, 'PaiTest123', 'Gnarhunters × Nike SB Dunk Low Pro Qs Black Black white', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220518/1652865848704.jpg?wh=750*600', 'DH7756-010', 1000.00, '2022-07-27 04:14:46', 0, 0, 0);
INSERT INTO `ums_member_read202207` VALUES (666, 17685, 6006, 'PaiTest123', 'Gnarhunters × Nike SB Dunk Low Pro Qs Black Black white', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220518/1652865848704.jpg?wh=750*600', 'DH7756-010', 1000.00, '2022-07-27 04:15:18', 0, 665, 0);
INSERT INTO `ums_member_read202207` VALUES (667, 17685, 6006, 'PaiTest123', 'Gnarhunters × Nike SB Dunk Low Pro Qs Black Black white', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220518/1652865848704.jpg?wh=750*600', 'DH7756-010', 1000.00, '2022-07-27 04:16:02', 0, 666, 0);
INSERT INTO `ums_member_read202207` VALUES (668, 17685, 6026, 'PaiTest123', 'adidas Kids Yeezy Slide ONYX', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220523/1653293331836.jpg?wh=750*600', 'HQ4115', 0.00, '2022-07-27 04:55:16', 0, 667, 0);
INSERT INTO `ums_member_read202207` VALUES (669, 17685, 6026, 'PaiTest123', 'adidas Kids Yeezy Slide ONYX', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220523/1653293331836.jpg?wh=750*600', 'HQ4115', 0.00, '2022-07-27 05:20:37', 0, 668, 0);
INSERT INTO `ums_member_read202207` VALUES (670, 17685, 6032, 'PaiTest123', 'Nike Air Jordan 1 Low Shadow Toe (GS)', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220524/1653354466056.jpg?wh=750*600', '553560-052', 0.00, '2022-07-27 11:55:14', 0, 0, 0);
INSERT INTO `ums_member_read202207` VALUES (671, 17685, 6032, 'PaiTest123', 'Nike Air Jordan 1 Low Shadow Toe (GS)', 'http://carryme-oss-prod.oss-ap-northeast-1.aliyuncs.com/mall/images/20220524/1653354466056.jpg?wh=750*600', '553560-052', 0.00, '2022-07-27 11:55:49', 0, 670, 0);
预想结果:
取到两张表里的最新的浏览量,获取如下 product_id,last_id,create
这里会有product_id 重复数据,同事的sql是这样写的
SELECT DISTINCTunion_read.product_id,union_read.create_time,union_read.last_id
FROM(SELECTproduct_id,create_time,last_id FROMums_member_read202206 WHEREid IN ( SELECT MAX( id ) FROM ums_member_read202206 WHERE create_time >= '2022-06-26 00:00:00' AND create_time <= '2022-06-30 23:59:59' AND member_id = '17685' GROUP BY product_id ) UNIONSELECTproduct_id,create_time,last_id FROMums_member_read202207 WHEREid IN ( SELECT MAX( id ) FROM ums_member_read202207 WHERE create_time >= '2022-07-01 00:00:00' AND create_time <= '2022-07-27 23:59:59' AND member_id = '17685' GROUP BY product_id ) ) AS union_read
ORDER BYunion_read.create_time DESC
原因分析和解决方案:
数据重复原因是应为 distinct 这个函数比较特殊 ,查询还必须放到首位,这样去重
select distinct 字段一,字段二,字段三
而同事想要拿到 三个值,只对字段一去重,这样写就会影响字段二和字段三,将他两也放到去重里,是不符合期望数据 ,于是我就想既然这样 distinct 是可以配合聚合函数使用 (SQL Server支持,而Access不支持)
select 字段一,字段二,字段三,count(distinct 字段一) as 字段四
但发现有一个报错
In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column ‘union_read.create_time’; this is incompatible with sql_mode=only_full_group_by
这是数据库版本引起的一个bug
由于太长跟本文也关系不大就放到最后 附录一
结果:
建议查询表查字段比较多,去重只有一个不要用distinct
换了个思路,换成GROUP BY
如下
SELECTproduct_id,create_time,last_id,max(last_id)
FROM(SELECTproduct_id,create_time,last_id FROMums_member_read202206 WHEREid IN ( SELECT MAX( id ) FROM ums_member_read202206 WHERE create_time >= '2022-06-26 00:00:00' AND create_time <= '2022-06-30 23:59:59' AND member_id = '17685' GROUP BY product_id ) UNIONSELECTproduct_id,create_time,last_id FROMums_member_read202207 WHEREid IN ( SELECT MAX( id ) FROM ums_member_read202207 WHERE create_time >= '2022-07-01 00:00:00' AND create_time <= '2022-07-27 23:59:59' AND member_id = '17685' GROUP BY product_id ) ) AS union_read
WHEREcreate_time >= '2022-06-28 00:00:00' AND create_time <= '2022-07-27 10:04:21'
GROUP BYproduct_id
ORDER BYmax(last_id) desc
创作不易,留个赞吧!
附录一(版本bug)
1:命令行中输入:
set sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’;
不过这种情况治标不治本,一旦mysql重启之后又会恢复。
2:修改MySQL的配置文件,
1、windows下找到MySQL的安装目录的my.ini文件,修改其中的配置为不启动ONLY_FULL_GROUP_BY模式
删掉带有ONLY_FULL_GROUP_BY的模式就ok了,如果没有找到my.ini文件。
去系统的隐藏文件夹查看,在某个盘下输入%ProgramData%然后搜索MySQL的my.ini文件
2、linux下找到my.cnf文件,这个是配置MySQL的文件。一般这个文件是在etc文件夹下。
vi my.cnf 编辑这个文件,然后在图示的位置上加入
sql_mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER"
然后重启MySQL服务:service mysqld restart
联合查询分组取最新数据相关推荐
- 1对多 只取一条 mysql_MySQL 多表关联一对多查询实现取最新一条数据的方法示例...
本文实例讲述了MySQL 多表关联一对多查询实现取最新一条数据的方法.分享给大家供大家参考,具体如下: MySQL 多表关联一对多查询取最新的一条数据 遇到的问题 多表关联一对多查询取最新的一条数据, ...
- 分组取最新的一条数据
##分组取最新的一条数据,错误 SELECTa.account_balance,a.deposit_amount,a.deposit_time,a.create_user,a.resident_id, ...
- 巧用row_number和partition by分组取top数据
2019独角兽企业重金招聘Python工程师标准>>> 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系统中取出每个学科前3名的学生.这种查询在SQL Server 20 ...
- tortoise无法拉取最新数据
使用tortoise有时无法拉取最新数据: 解决方法: 使用Git Bash Here,然后使用git pull命令
- stream实现list根据对象中多个属性分组,并取分组后最新数据
业务场景:定时任务同步中间表数据到业务表,如果中间表中存在相同维度的多条数据(未创建唯一索引),取最新一条数据,并对查询的中间表数据进行更新. 方式1 // 根据结果表唯一索引分组,取中间表重复最新一 ...
- mysql分组取最新时间的数据
mysql分组后显示最新数据 方法一:NOT EXISTS SELECT e.GROUP_COLUMN, e.COMPARE_TIME FROM ...
- 如何分组取最新的数据
今天有个朋友问我:mysql 根据某个id进行分组,每个分组按时间排序取最新的一条记录,除了使用row_number函数,是否还有其他方法? 其实这是个老生常谈的问题了 ,并且会经常出现在各种面试题中 ...
- mysql分组取所有数据_mysql 分组后取每个组内最新的一条数据
首先,将按条件查询并排序的结果查询出来. mysql> select accepttime,user,job from tuser_job where user =8 order by acce ...
- mysql 分组取最新的一条记录(整条记录)
方法:mysql取分组后最新的一条记录,下面两种方法.一种是先筛选 出最大和最新的时间,在连表查询.一种是先排序,然后在次分组查询(默认第一条),就是最新的一条数据了 #select * from t ...
最新文章
- NHibernate初学体验记
- 机器人组团到城市打工,第一站果然是赛博朋克城
- Scrapy框架的学习(5.scarpy实现翻页爬虫,以及scrapy.Request的相关参数介绍)
- 学习3dmax的第二天
- linux重启后地址不是之前设置的静态地址的解决方案
- 关于类和接口的一些小笔记
- .NET开发人员十大必备下载工具
- 邀请合作如何表达_如何邀请大咖嘉宾来商群分享
- FPGA阻塞赋值与非阻塞赋值用法
- python数组如果余弦_numpy :: 计算特征之间的余弦距离
- 计算机科学家壁纸,科幻宇宙星球CG壁纸
- Mysql:日志管理:二进制事务日志
- 个人笔记1:display与visibility用法
- IDEA Translation插件,有道智云(有道翻译)应用ID,密钥申请教程
- W5500+STM32F103C8T6进行TCP通信(modbus)
- web开发表情包---微信表情
- DOTA全英雄装备介绍+物品简称[图文]
- excel2016html,Excel2016中切换至全屏视图的两种方法
- 微信炸弹不在服务器,微信隐藏“沙雕”功能!炸弹+“便便”炸飞聊天框
- 企业成长启示录:立业,首当立人?
热门文章
- Java 随机点名器
- Python基础 | 快速实现label_to_index
- ArcGIS专题制图(一):制图中如何给图层增加阴影立体效果
- 学习实践-Vicuna【小羊驼】(部署+运行)
- python: 内建函式round() 是四舍五入还是五舍六入?
- 代码 bug 嗅探器:Sanitizer
- 中国的黑客究竟有多张狂?
- 三菱PLC步进伺服控制程序 用三菱plc和威纶触摸屏编写
- c语言isfinite_visual-c-std :: isfinite在MSVC上
- 深度揭密SSD中的原片/白片/黑片:莫贪小便宜