SQL|where, group by, order by去重实例之如何正确使用group by

需求

找出最近练习过的句子id,不能重复(练习保存在practice表中,句子保存在pth_sentences表中,一个pth_sentence纪录有多条practices纪录)。现在的情况是如果一个句子练习多次,会得到重复的pth_sentence_id,这样前端在列出来的时候呢,句子是重复的,我只想让句子显示一次,既pth_sentence_id只出现一次。

image-20210930161015127

Practices的表结构是这样的:

CREATE TABLE `practices` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `pth_sentence_id` int(11) DEFAULT NULL,
  `local_sound` varchar(255) DEFAULT NULL,
  `comment` varchar(255) DEFAULT NULL,
  `created_at` datetime(6) NOT NULL,
  `updated_at` datetime(6) NOT NULL,
  `soundfile` json DEFAULT NULL,
  `del` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=215 DEFAULT CHARSET=utf8mb4;

一步步写出满足需求的SQL语句好喽,以前老师就是这么教的。

最近句子练习纪录5条

so easy. 问题就是句子id有重复,需要去重。

image-20210930161209424

加入group by

select * from practices
order by created_at desc
group by pth_sentence_id
limit 5

出错了

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘group by pth_sentence_id
limit 10’ at line 3

为啥呢?order by 需要在group by 的后面执行!并且要用where语句的话需要放在group by之前!

调整下顺序:

select * from practices
group by pth_sentence_id
order by created_at desc
limit 5

还是出错,请原谅我好久没写SQL了:

1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘beginner.practices.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

为啥呢?因为id没有写在group by 语句中, group by 是要与聚合函数结合起来使用的。

好,我不写id了,改成这样呢?

select pth_sentence_id from practices
group by pth_sentence_id
order by created_at desc
limit 5

继续出错。

1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ‘beginner.practices.created_at’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

这回是group by中的created_at呢,说没有在group_by语句中。好,加进去。

倒是没错了,但结果不是我想要的,因为这连个id都没有,而且数据有重复。

image-20210930153603737

加入id

怎么把id加进去呢?需要使用聚合函数,比如max, min这样的,看你实际的需要。

image-20210930180637006

我这个例子里面加上max相当于说我要找出一个句子的练习中practice.id最大的那一个practice纪录!

但如果在group by里面添加created_at之后并没有去重,查了下,这种group by会同时在pth_sentence_id和created_at两个字段进行分组,不是按照pth_sentence_id这一个条件进行分组,这就需要最后神奇的下一步:

image-20210930180816059

order by中加入max

order by 中的日期排序添加上max聚合函数,且:group by里面只有一个分组条件,pth_sentence_id,这样就得到了包含唯一pth_sentence_id的practices纪录,并且还是最近生成(按照created_at倒序排列)的5条practice记录。

加入where语句

最近的几次练习都是用户6的,所以与上面结果一致。

image-20210930182631766

关于为什么order by里面使用max能起作用,我还在研究中, 有哪位大师能指导一二?或许您有更方便的办法?

关注爱玩的安哥,学习更多有用知识

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SQL中,使用GROUP BY子句可以根据指定的列对结果进行分组,并将每个组的聚合结果返回。如果你想要使用GROUP BY去重,你可以根据需要选择一个或多个列,并在SELECT子句中使用DISTINCT关键字来返回唯一的值。 例如,假设有一个名为"students"的表,其中包含学生的姓名和学号。如果你想要按照学号去重,并返回每个学号对应的唯一姓名,你可以使用以下SQL查询语句: SELECT DISTINCT student_id, student_name FROM students GROUP BY student_id; 这样就会返回每个学号对应的唯一姓名,并去除重复的学号。 希望这个回答对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [SQLwhere, group by, order by去重实例之如何正确使用group by](https://blog.csdn.net/weixin_42293131/article/details/120571139)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [sql中的去重group by的理解](https://blog.csdn.net/weixin_52110757/article/details/127617781)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱玩的安哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值