场景: 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. 1对多 只取一条 mysql_MySQL 多表关联一对多查询实现取最新一条数据的方法示例...

    本文实例讲述了MySQL 多表关联一对多查询实现取最新一条数据的方法.分享给大家供大家参考,具体如下: MySQL 多表关联一对多查询取最新的一条数据 遇到的问题 多表关联一对多查询取最新的一条数据, ...

  2. 分组取最新的一条数据

    ##分组取最新的一条数据,错误 SELECTa.account_balance,a.deposit_amount,a.deposit_time,a.create_user,a.resident_id, ...

  3. 巧用row_number和partition by分组取top数据

    2019独角兽企业重金招聘Python工程师标准>>> 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系统中取出每个学科前3名的学生.这种查询在SQL Server 20 ...

  4. tortoise无法拉取最新数据

    使用tortoise有时无法拉取最新数据: 解决方法: 使用Git Bash Here,然后使用git pull命令

  5. stream实现list根据对象中多个属性分组,并取分组后最新数据

    业务场景:定时任务同步中间表数据到业务表,如果中间表中存在相同维度的多条数据(未创建唯一索引),取最新一条数据,并对查询的中间表数据进行更新. 方式1 // 根据结果表唯一索引分组,取中间表重复最新一 ...

  6. mysql分组取最新时间的数据

    mysql分组后显示最新数据 方法一:NOT EXISTS SELECT         e.GROUP_COLUMN,         e.COMPARE_TIME     FROM        ...

  7. 如何分组取最新的数据

    今天有个朋友问我:mysql 根据某个id进行分组,每个分组按时间排序取最新的一条记录,除了使用row_number函数,是否还有其他方法? 其实这是个老生常谈的问题了 ,并且会经常出现在各种面试题中 ...

  8. mysql分组取所有数据_mysql 分组后取每个组内最新的一条数据

    首先,将按条件查询并排序的结果查询出来. mysql> select accepttime,user,job from tuser_job where user =8 order by acce ...

  9. mysql 分组取最新的一条记录(整条记录)

    方法:mysql取分组后最新的一条记录,下面两种方法.一种是先筛选 出最大和最新的时间,在连表查询.一种是先排序,然后在次分组查询(默认第一条),就是最新的一条数据了 #select * from t ...

最新文章

  1. NHibernate初学体验记
  2. 机器人组团到城市打工,第一站果然是赛博朋克城
  3. Scrapy框架的学习(5.scarpy实现翻页爬虫,以及scrapy.Request的相关参数介绍)
  4. 学习3dmax的第二天
  5. linux重启后地址不是之前设置的静态地址的解决方案
  6. 关于类和接口的一些小笔记
  7. .NET开发人员十大必备下载工具
  8. 邀请合作如何表达_如何邀请大咖嘉宾来商群分享
  9. FPGA阻塞赋值与非阻塞赋值用法
  10. python数组如果余弦_numpy :: 计算特征之间的余弦距离
  11. 计算机科学家壁纸,科幻宇宙星球CG壁纸
  12. Mysql:日志管理:二进制事务日志
  13. 个人笔记1:display与visibility用法
  14. IDEA Translation插件,有道智云(有道翻译)应用ID,密钥申请教程
  15. W5500+STM32F103C8T6进行TCP通信(modbus)
  16. web开发表情包---微信表情
  17. DOTA全英雄装备介绍+物品简称[图文]
  18. excel2016html,Excel2016中切换至全屏视图的两种方法
  19. 微信炸弹不在服务器,微信隐藏“沙雕”功能!炸弹+“便便”炸飞聊天框
  20. 企业成长启示录:立业,首当立人?

热门文章

  1. Java 随机点名器
  2. Python基础 | 快速实现label_to_index
  3. ArcGIS专题制图(一):制图中如何给图层增加阴影立体效果
  4. 学习实践-Vicuna【小羊驼】(部署+运行)
  5. python: 内建函式round() 是四舍五入还是五舍六入?
  6. 代码 bug 嗅探器:Sanitizer
  7. 中国的黑客究竟有多张狂?
  8. 三菱PLC步进伺服控制程序 用三菱plc和威纶触摸屏编写
  9. c语言isfinite_visual-c-std :: isfinite在MSVC上
  10. 深度揭密SSD中的原片/白片/黑片:莫贪小便宜