联合查询分组取最新数据

场景: 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  DISTINCT
	union_read.product_id,
	union_read.create_time,
	union_read.last_id 
FROM
	(
	SELECT
		product_id,
		create_time,
		last_id 
	FROM
		ums_member_read202206 
	WHERE
		id 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 ) UNION
	SELECT
		product_id,
		create_time,
		last_id 
	FROM
		ums_member_read202207 
	WHERE
		id 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 BY
	union_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
如下

	SELECT
	product_id,
	create_time,
	last_id,
	max(last_id)
FROM
	(
	SELECT
		product_id,
		create_time,
		last_id 
	FROM
		ums_member_read202206 
	WHERE
		id 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 ) UNION
	SELECT
		product_id,
		create_time,
		last_id 
	FROM
		ums_member_read202207 
	WHERE
		id 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 
WHERE
	create_time >= '2022-06-28 00:00:00' 
	AND create_time <= '2022-07-27 10:04:21' 
GROUP BY
	product_id
ORDER BY
	max(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小*-^-*九

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值