mysql中过滤重复记录之distinct用法

本文章主要是讲述了关于利用mysqldistinct过滤一些重启的记录,有需要的朋友可参考一下。

下面我们就通过几个简单的 query 示例来展示一下 distinct 的实现。

1.首先看看通过松散索引扫描完成 DISTINCT 的操作:

 代码如下复制代码 sky@localhost : example 11:03:41> EXPLAIN SELECT DISTINCT group_id
    -> FROM group_messageG
*************************** 1. row ***************************
           id: 1
  SELECT_type: SIMPLE
        table: group_message
         type: range
possible_keys: NULL
          key: idx_gid_uid_gc
      key_len: 4
          ref: NULL
         rows: 10
        Extra: Using index for group-by
1 row in set (0.00 sec)

我们可以很清晰的看到,执行计划中的 Extra 信息为“Using index for group-by”,这代表什么意思?为什么我没有进行 GROUP BY 操作的时候,执行计划中会告诉我这里通过索引进行了 GROUP BY 呢?其实这就是于 DISTINCT 的实现原理相关的,在实现 DISTINCT的过程中,同样也是需要分组的,然后再从每组数据中取出一条返回给客户端。而这里的 Extra 信息就告诉我们,MySQL 利用松散索引扫描就完成了整个操作。当然,如果 MySQL Query Optimizer 要是能够做的再人性化一点将这里的信息换成“Using index for distinct”那就更好更容易让人理解了,呵呵。

2.我们再来看看通过紧凑索引扫描的示例:

 代码如下复制代码 sky@localhost : example 11:03:53>  EXPLAIN SELECT DISTINCT user_id
    -> FROM group_message
    -> WHERE group_id = 2G
*************************** 1. row ***************************
           id: 1
  SELECT_type: SIMPLE
        table: group_message
         type: ref
possible_keys: idx_gid_uid_gc
          key: idx_gid_uid_gc
      key_len: 4
          ref: const
         rows: 4
        Extra: Using WHERE; Using index
1 row in set (0.00 sec)

这里的显示和通过紧凑索引扫描实现 GROUP BY 也完全一样。实际上,这个 Query 的实现过程中,MySQL 会让存储引擎扫描 group_id = 2 的所有索引键,得出所有的 user_id,然后利用索引的已排序特性,每更换一个 user_id 的索引键值的时候保留一条信息,即可在扫描完所有 gruop_id = 2 的索引键的时候完成整个 DISTINCT 操作。

3.下面我们在看看无法单独使用索引即可完成 DISTINCT 的时候会是怎样:

 代码如下复制代码 sky@localhost : example 11:04:40> EXPLAIN SELECT DISTINCT user_id
    -> FROM group_message
    -> WHERE group_id > 1 AND group_id *************************** 1. row ***************************
           id: 1
  SELECT_type: SIMPLE
        table: group_message
         type: range
possible_keys: idx_gid_uid_gc
          key: idx_gid_uid_gc
      key_len: 4
          ref: NULL
         rows: 32
        Extra: Using WHERE; Using index; Using temporary
1 row in set (0.00 sec)

当 MySQL 无法仅仅依赖索引即可完成 DISTINCT 操作的时候,就不得不使用临时表来进行相应的操作了。但是我们可以看到,在 MySQL 利用临时表来完成 DISTINCT 的时候,和处理 GROUP BY 有一点区别,就是少了 filesort。实际上,在 MySQL 的分组算法中,并不一定非要排序才能完成分组操作的,这一点在上面的 GROUP BY 优化小技巧中我已经提到过了。实际上这里 MySQL 正是在没有排序的情况下实现分组最后完成 DISTINCT 操作的,所以少了 filesort 这个排序操作。

4.最后再和 GROUP BY 结合试试看:
 

 代码如下复制代码 sky@localhost : example 11:05:06> EXPLAIN SELECT DISTINCT max(user_id)
    -> FROM group_message
    -> WHERE group_id > 1 AND group_id     -> GROUP BY group_idG
*************************** 1. row ***************************
           id: 1
  SELECT_type: SIMPLE
        table: group_message
         type: range
possible_keys: idx_gid_uid_gc
          key: idx_gid_uid_gc
      key_len: 4
          ref: NULL
         rows: 32
        Extra: Using WHERE; Using index; Using temporary; Using filesort
1 row in set (0.00 sec)

最后我们再看一下这个和 GROUP BY 一起使用带有聚合函数的示例,和上面第三个示例相比,可以看到已经多了 filesort 排序操作了,正是因为我们使用了 MAX 函数的缘故。要取得分组后的 MAX 值,又无法使用索引完成操作,只能通过排序才行了。

在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久

下面先来看看例子:

 代码如下复制代码

   table
   id name
   1 a
   2 b
   3 c
   4 c
   5 b

库结构大概这样,这只是一个简单的例子,实际情况会复杂得多

比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录

 

 代码如下复制代码    select distinct name from table

得到的结果是:

 

 代码如下复制代码    name
   a
   b
   c

好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:

 

 代码如下复制代码     select distinct name, id from table

结果会是:

 代码如下复制代码

   id name
   1 a
   2 b
   3 c
   4 c
   5 b

distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除,我们再改改查询语句:

 

 代码如下复制代码 select id, distinct name from table

很遗憾,除了错误信息你什么也得不到,distinct必须放在开头,难到不能把distinct放到where条件里?能,照样报错。。。。。。。

试了半天,也不行,最后在mysql手册里找到一个用法,用group_concat(distinct name)配合group by name实现了我所需要的功能,兴奋,天佑我也,赶快试试

报错。。。。。。。。。。。。郁闷。。。。。。。连mysql手册也跟我过不去,先给了我希望,然后又把我推向失望,好狠那。。。。

再仔细一查,group_concat函数是4.1支持,晕,我4.0的。没办法,升级,升完级一试,成功。。。。。。

终于搞定了,不过这样一来,又必须要求客户也升级了

突然灵机一闪,既然可以使用group_concat函数,那其它函数能行吗?

降重鸟 降重鸟

要想效果好,就用降重鸟。AI改写智能降低AIGC率和重复率。

降重鸟 113 查看详情 降重鸟

赶紧用count函数一试,成功,我。。。。。。。想哭啊,费了这么多工夫。。。。。。。。原来就这么简单。。。。。。

现在将完整语句放出:

 代码如下复制代码

    select id,name, count(distinct name) from table group by name

结果:

 代码如下复制代码

   id name count(distinct name)
   1 a 1
   2 b 1
   3 c 1

最后一项是多余的,不用管就行了,目的达到。。。。。

哦,对,再顺便说一句,group by 必须放在 order by 和 limit之前,不然会报错,差不多了,我继续忙碌。。。。。。

原文

这篇文章是我从别人那里转来的,在自己的项目中也遇到了这样的问题,我的sql语句是向下面这样写的:

 

 代码如下复制代码

   SELECT attention_join.memberID,nickName,headpic,attention_join.time

    FROM attention_join

        JOIN member ON attention_join.memberID = member.memberID

        JOIN member_meta ON member.memberID = member_meta.memberID

    GROUP BY attention_join.memberID

    ORDER BY attention_join.time DESC

意思是 ‘按 加入/关注 小组的时间降序,查出小组内的会员’ ,但是语句里并没有用到向上文说的count()关键字,这个也让我很不解,mysql没有详细的学习过,它的 group by 关键字的用法好像和 sqlserver 的有很大不同,这个等有时间了,在查查看吧,现在没有时间了

哦,对了,我的mysql版本是:

 服务器版本: 5.1.54-1 ubuntu4

 协议版本: 10

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/489567.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 15:04:58
下一篇 2025年11月8日 15:06:21

相关推荐

  • php函数与数据库交互的完整指南

    使用 php 函数操作 mysql 数据库涉及以下步骤:使用 mysqli_connect() 建立数据库连接使用 mysqli_query() 执行 sql 查询使用 mysqli_query() 插入数据使用 mysqli_query() 更新数据使用 mysqli_query() 删除数据 使…

    2025年12月9日
    000
  • Laravel 入门:查询生成器初学者指南

    laravel 的 查询生成器 提供了一个强大、流畅的界面,用于在 php 中构建 sql 查询。它允许您以富有表现力的、类似 sql 的语法与数据库交互,同时抽象出大部分复杂性。 我们将演练 laravel 应用程序中的典型用例,使用查询生成器执行各种任务,例如选择、插入、更新和删除数据。 第 1…

    2025年12月9日
    000
  • php函数跨平台兼容性秘诀

    秘诀一:使用 php 内置函数,最大限度减少跨平台兼容性问题。秘诀二:避免硬编码路径,使用相对路径或 php 常量引用文件和目录。秘诀三:考虑操作系统差异,在函数中进行适当调整。秘诀四:使用多平台函数库,例如 pear 或 symfony components。实战案例:跨平台文件读取函数使用相对路…

    2025年12月9日
    000
  • PHP 函数如何使用 MySQL 调用外部函数?

    PHP 函数如何使用 MySQL 调用外部函数? 在 MySQL 中,外部函数是被定义在数据库之外的可执行程序或库,可以在查询中调用。PHP 提供了 mysqli_register_func() 和 mysqli_external_function() 函数,使您可以将 PHP 函数注册为 MySQ…

    2025年12月9日
    000
  • PHP异常处理中的堆栈跟踪功能详解

    堆栈跟踪是 php 异常处理中的功能,通过 $e->gettrace() 获取,包含异常发生的文件路径、函数名称、参数值、类名和方法名。它能帮助定位和修复错误,如示例中展示的调试数据库查询,通过堆栈跟踪可快速定位到错误函数和原因。 PHP异常处理中的堆栈跟踪功能详解 堆栈跟踪,是在 PHP 中…

    2025年12月9日
    000
  • PHP 函数内存泄露检测与修复指南

    PHP 函数内存泄露检测与修复指南 引言 内存泄露是指由于编程不当或缺陷,导致 PHP 应用驻留内存,即使程序不再需要它们。这可能导致性能下降、服务器崩溃,甚至应用程序崩溃。 内存泄露的检测 立即学习“PHP免费学习笔记(深入)”; 有几种检测 PHP 内存泄漏的方法: 使用 PHP 内置的 mem…

    2025年12月9日
    000
  • 如何针对不同平台和系统优化 PHP 函数和 C 扩展交互?

    针对不同平台和系统优化 php 函数和 c 扩展交互的答案如下:优化交互时,首先确定 c 扩展的瓶颈。根据平台选择适当的数据结构。优化内存分配以避免碎片和性能下降。在多线程环境中使用线程安全技术。优化 php 函数和 c 扩展交互可以提高性能、可靠性和兼容性,释放扩展的全部潜力。 如何针对不同平台和…

    2025年12月9日
    000
  • 剖析 PHP 函数执行的瓶颈

    php 函数执行瓶颈包括数据库查询、网络 i/o、内存分配、计算复杂度和锁定。剖析工具(如 xdebug、blackfire 和 tideways)有助于识别瓶颈。数据库查询可通过优化连接、索引和缓存进行优化;网络 i/o 可通过减少调用、使用缓存和批量处理得到优化;内存管理可通过弱引用和对象回收得…

    2025年12月9日
    000
  • PHP函数中异常处理的机制和原理是什么?

    php 异常处理机制允许捕获和处理运行时错误和异常情况,通过异常类来表示错误类型,通过 try-catch 块捕获异常,并通过异常对象获取错误详细信息,从而提升错误隔离、代码清晰度和用户体验。 PHP 函数中的异常处理机制 异常处理机制是一种处理运行时错误和异常情况的机制。PHP 中的异常处理机制允…

    2025年12月9日
    000
  • 提高 PHP 效率:经过验证的性能优化技术

    优化 php 性能可确保我们的 web 应用程序平稳运行、快速响应并高效处理流量。下面是关于如何有效地最大化 php 性能的详细分步指南,并为每种优化策略提供了实践示例。 第 1 部分:更新到最新的稳定 php 版本 第 1 步:检查当前 php 版本 首先检查系统上安装的当前 php 版本: ph…

    2025年12月9日
    000
  • PHP 匿名函数在处理数据结构中的应用

    php 匿名函数在数据结构处理中的应用:轻松处理数组,例如通过匿名函数排序。方便处理对象,例如通过匿名函数筛选满足条件的对象。在处理 mysql 查询结果时提供灵活性和简便性,例如匿名函数可用于提取特定列数据。 PHP 匿名函数在处理数据结构中的应用 引言 匿名函数,也称为闭包,是 PHP 中一种强…

    2025年12月9日
    000
  • 使用 PHP 匿名函数中的命名空间?

    php 匿名函数可以在命名空间中定义,继承命名空间中的类、常量和函数。为了访问外部变量,匿名函数可以使用 use 子句捕获它们,即使是在命名空间之外声明的变量。 使用 PHP 匿名函数中的命名空间 PHP 匿名函数提供了一种定义不需要命名函数的便捷方式。但是,匿名函数不能直接访问其包含范围之外的变量…

    2025年12月9日
    000
  • PHP 函数参数绑定在组合函数中的应用?

    php参数绑定在组合函数中通过将变量绑定到查询中的命名参数,可以防止sql注入并提高效率。具体步骤包括:创建数据库连接。准备一个带有命名参数的查询。使用bindparam方法绑定变量到参数。执行查询。获取结果或更新记录数。 PHP 参数绑定在组合函数中的用法 参数绑定是一种节省资源的技术,它可以防止…

    2025年12月9日
    000
  • 不同数据库系统中参数绑定的实现有何异同?

    不同数据库系统中,参数绑定实现的差异主要体现在:参数占位符:常见占位符为问号;准备语句:用于优化查询执行,在准备阶段提供参数值;类型化:不同系统对参数类型化处理不同,有的强制执行,有的允许动态绑定;sql 执行:系统通过匹配参数值和占位符进行操作,处理空值和越界值策略也有差异。 不同数据库系统中参数…

    2025年12月9日
    000
  • 参数绑定在 PHP 代码测试中的作用

    php 单元测试中,参数绑定可增强代码可读性、可维护性和可靠性。它通过使用占位符将输入数据与查询分开,防止 sql 注入攻击,并简化查询更新和维护。 参数绑定在 PHP 代码测试中的作用 引言 参数绑定是一个在 PHP 单元测试中管理数据库交互的宝贵工具。它通过使用占位符将输入数据与查询分开,从而增…

    2025年12月9日
    000
  • PHP 函数参数绑定的目的和作用?

    PHP 函数参数绑定的目的和作用 目的 参数绑定是允许在执行 SQL 查询时动态传递参数的一种技术。它的目的是提高安全性、性能和灵活性。 作用 立即学习“PHP免费学习笔记(深入)”; PHP 函数参数绑定主要用于: 防止 SQL 注入漏洞:通过将参数值与 SQL 查询分开,它可以防止攻击者在输入中…

    2025年12月9日
    000
  • 保护 PHP 应用程序免受 SQL 注入攻击

    阻止 sql 注入攻击对于维护 php 应用程序的安全至关重要。 sql 注入是一个漏洞,允许攻击者在您的数据库上执行任意 sql 代码,可能导致数据泄露或丢失。这是防止 php 中 sql 注入攻击的分步指南,配有实践示例和说明。 1.了解 sql 注入 当用户输入未正确清理并合并到 sql 查询…

    2025年12月9日
    000
  • 使用迁移在 Laravel 中进行数据库架构管理:深入教程

    laravel 迁移是管理数据库架构更改的好方法。它们允许您对数据库结构进行版本控制,并随时间轻松回滚或修改更改。在本指南中,我们将逐步探索在 laravel 中创建、运行和回滚迁移的过程,并提供一个实践示例。 第 1 步:设置 laravel 环境 开始迁移之前,请确保已安装 laravel。您可…

    2025年12月9日
    000
  • PHP 函数参数绑定的最佳实践?

    PHP 函数参数绑定的最佳实践 什么是参数绑定? 参数绑定是一种将值传递给函数参数的技巧,它可以防止 SQL 注入攻击。它涉及在 SQL 查询中使用占位符,然后使用一个单独的过程将值绑定到这些占位符。 最佳实践 立即学习“PHP免费学习笔记(深入)”; 总是使用参数绑定:为函数参数指定值时,使用参数…

    2025年12月9日
    000
  • PHP 参数绑定与 PDO 的关系

    PHP 参数绑定与 PDO 的关系 参数绑定是 PHP 数据对象 (PDO) 中一项重要的功能,它允许我们在执行查询之前将参数传递给 SQL 语句。通过使用参数绑定,我们可以防止 SQL 注入攻击,并提高代码的可读性和可维护性。 如何使用参数绑定 要使用参数绑定,我们需要使用 PDO::prepar…

    2025年12月9日
    000

发表回复

登录后才能评论
关注微信