2023-03-21  阅读(2)
原文作者:简单教程 原文地址:https://www.twle.cn/c/yufei/mysqlfav/mysqlfav-basic-distinct.html

即使在自己记忆力最好的时候,也是记不住 MySQL DISTINCT 的用法。我一直对这个记不住好奇,想不明白,为什么。

前几天翻 MySQL 手册,看到 DISTINCT 又发现自己似乎忘记。

我真的忘记了吗 ?

好像也没有,就是会混淆,到底 DISTINCT 要不要加括号 () ,不加括号又是什么情况呢 ? 这两个记不住

范例数据

在继续之前,我们先需要一个 MySQL 服务器和服务器上的一个 test 数据库中的一个 fruits

创建表和数据的语句如下

    CREATE DATABASE IF NOT EXISTS test default character set utf8mb4 collate utf8mb4_unicode_ci;
    
    use test;
    
    CREATE TABLE IF NOT EXISTS `fruits`(
       `id` INT UNSIGNED AUTO_INCREMENT,
       `user` VARCHAR(64) NOT NULL,
       `fruit` VARCHAR(128) NOT NULL,
       `owns` INTEGER(11) NOT NULL,
       PRIMARY KEY ( `id` )
    )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    INSERT INTO fruits(user,fruit,owns) VALUES ('yufei','apple',3),
    ('yufei','banana',5),
    ('yufei','peach',3),
    ('hero','apple',3),
    ('hero','peach',3),
    ('hero','pear',5);

运行完语句后,fruits 表显示数据如下

    mysql> SELECT * FROM fruits;
    +----+-------+--------+------+
    | id | user  | fruit  | owns |
    +----+-------+--------+------+
    |  1 | yufei | apple  |    3 |
    |  2 | yufei | banana |    5 |
    |  3 | yufei | peach  |    3 |
    |  4 | hero  | apple  |    3 |
    |  5 | hero  | peach  |    3 |
    |  6 | hero  | pear   |    5 |
    +----+-------+--------+------+

MySQL DISTINCT 的作用

我们先来看看 MySQL DISTINCT 的作用,其实就是几个字

「 排除重复的行 」

但是,就是因为字少,没有给个限定,如何排除重复的行呢 ?

答案是

「 根据参数所指定的列排除重复的行 」

坑来了,DISTINCT 有带括号和没括号的两种用法,这两种是如何指定参数的呢 ?

等等... 这个官方没给答案...,我们使用过程中发现

  1. 如果跟其它函数结合使用,那么只会使用小括号内的参数
  2. 否则,那么 DISTINCT 关键字后的所有列都是参数

MySQL DISTINCT 的位置

千万不要认为 DISTINCT 只能放在开头,也不要认为 DISTINCT 可以放在任意位置。

这个关键字的位置是有讲究的:

1. 单独的 DISTINCT 关键字只能放在开头,放在其它位置会报错

比如我们要根据 user 来获取不重复的行,如果像下面这样把 DISTINCT 放在中间是会报错的

    mysql> SELECT id, DISTINCT ( user ),fruit,owns FROM fruits;
    ERROR 1064 (42000): 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 'DISTINCT ( user ),fruit,owns FROM fruits' at line 1

但如果放在开头,则不会

    mysql> SELECT DISTINCT ( user ),id,fruit,owns FROM fruits;
    +-------+----+--------+------+
    | user  | id | fruit  | owns |
    +-------+----+--------+------+
    | yufei |  1 | apple  |    3 |
    | yufei |  2 | banana |    5 |
    | yufei |  3 | peach  |    3 |
    | hero  |  4 | apple  |    3 |
    | hero  |  5 | peach  |    3 |
    | hero  |  6 | pear   |    5 |
    +-------+----+--------+------+

好诡异的用法,好诡异的结果 ( 为啥数据会全部显示 ?)

2. 但如果是配合其它的函数使用,比如 COUNT() 则可以任意位置

其实这句话不严谨,应该是其它函数可以任意位置时,DISTINCT 也可以任意位置

    mysql> SELECT COUNT(DISTINCT ( user )),fruit FROM fruits;
    +--------------------------+-------+
    | COUNT(DISTINCT ( user )) | fruit |
    +--------------------------+-------+
    |                        2 | apple |
    +--------------------------+-------+

好诡异的结果!!!!

COUNT(DISTINCT ( user )) 放在末尾以一样

    mysql> SELECT fruit, COUNT(DISTINCT ( user )) FROM fruits;
    +-------+--------------------------+
    | fruit | COUNT(DISTINCT ( user )) |
    +-------+--------------------------+
    | apple |                        2 |
    +-------+--------------------------+
    1 row in set (0.00 sec)

这个结果简直诡异到怀疑人生?

至于为什么会这样,我们下一章节再来解释


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文