找出最近不重复数据的sql写法

SQL查询最近不重复数据技巧
本文介绍如何使用SQL查询最近不重复的数据记录。通过在子查询中利用用户ID和最大投票时间,再结合主查询,可以筛选出最近的唯一用户活动记录。示例SQL语句展示了从table表中按用户ID分组,获取每个用户最新的记录,并按时间降序排列,最后限制返回结果的前10条。
现在有个需求,要找出给某活动投票的前10个人,按照投票时间从新到旧排序。而每个活动每人可以多次投票。
项目中应该经常碰到这种问题,像我这种小菜鸟,经常的做法是分两条sql,或嵌套查询,或查询后用程序二次处理。
我试着找出更简单的写法,现分享出来。

突然想到这和在淘宝等网购平台的 ‘最近有n人也浏览了该商品’ 功能类似哇。如果仅认为它走数据库,那是否也如出此辙呢。

切入正题,拿投票来举例,模拟些数据:

用户ID     投票时间
   1      2001
   2      2002
   3      2003
   1      2004
   2      2005


按照项目要求,最终得到的数据应是:

用户ID     投票时间
   2      2005
   1      2004
   3      2003

最先想到这两种写法:
1. select distinct 用户ID from table
2. select 用户ID from table group by '用户ID'

后来把第2条sql加工一下,最终sql为:
SELECT 用户ID,max(投票时间) time FROM table group by 用户ID order by time DESC  limit 10

如果要查询出整条记录写法为:

SELECT * FROM table where (用户ID,time) in  (SELECT 用户ID,max(投票时间) time FROM table group by 用户ID)  order by time DESC  limit 10


分析:
max(投票时间) 将会在 group by 子结果集下挑出一个最大时间的数据作为分组后的结果
然而要按时间从新到旧,order by 必须依据max(投票时间)的新字段 time 进行排序 。

如果有错误或更好的建议,也欢迎交流。
SQL 中,实现重复查询有多种方法,以下是一些常见的方式: ### 使用 `DISTINCT` 关键字 `DISTINCT` 关键字用于返回唯一同的值。当在 `SELECT` 语句中使用 `DISTINCT` 时,它会自动去除结果集中的重复行。 #### 示例 1:查询单个字段重复的记录 ```sql SELECT DISTINCT username FROM msg; ``` 该语句会从 `msg` 表中查询 `username` 字段重复的记录。需要注意的是,`SELECT DISTINCT` 后面若跟多个字段,可能会产生误解,因为它作用于整个选择列表,要确保需求与使用方式匹配。例如,错误写法 `SELECT DISTINCT [字段名] ,[其他字段名] FROM [表名] WHERE [检索件字句]` 可能会使检索结果仍含重复项,因为 `DISTINCT` 会对整个选择列表去重,而是仅对指定的第一个字段去重 [^3]。 #### 示例 2:查询多个字段组合重复的记录 ```sql SELECT DISTINCT column1, column2 FROM your_table; ``` 此语句会返回 `your_table` 表中 `column1` 和 `column2` 组合重复的记录。 #### 示例 3:对截取后的字段进行重复查询 ```sql SELECT DISTINCT substr(report_date, 0, 4) FROM report; ``` 该语句从 `report` 表中截取 `report_date` 字段的前 4 个字符,并返回重复的结果 [^2]。 ### 使用 `GROUP BY` 和 `HAVING` 子句 通过 `GROUP BY` 对数据进行分组,再结合 `HAVING` 子句筛选出符合件的组,可实现重复查询。 #### 示例:查询重复的所有记录 ```sql SELECT * FROM table WHERE name IN (SELECT name FROM table GROUP BY name HAVING COUNT(name) = 1); ``` 此语句先通过子查询 `SELECT name FROM table GROUP BY name HAVING COUNT(name) = 1` 找出 `name` 字段只出现一次的 `name` 值,然后外层查询从 `table` 表中筛选出 `name` 在这些值中的所有记录,从而得到重复的所有记录 [^1]。 ### 处理多列组合去重且列值可能拼接重复的情况(以 Oracle 为例) 当遇到多列组合去重,且直接拼接列值可能导致重复判断准确时,可加入特殊字符来解决。例如,若确定两列字段中会出现 `#` 这样的字符内容,可使用如下语句: ```sql -- 假设 t 是表的别名,address 和 customer_name 是列名 SELECT * FROM your_table t WHERE (t.address || '#' || t.customer_name) IN (SELECT t.address || '#' || t.customer_name FROM your_table t GROUP BY t.address || '#' || t.customer_name HAVING COUNT(*) = 1); ``` 该语句通过在两列之间加入特殊字符 `#` 进行拼接,再进行分组和筛选,以准确找出重复的记录 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值