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

上一章节我们学习了 SQL DISTINCT 的位置对结果的影响。但我们还没深入到 MySQL DISTINCT 关键字的核心用法,同时,我们也还未讲解 DISTINCT 有无小括号是否有影响等,这些,我们会在这一章节全部讲完。

DISTINCT 中的小括号 ()

「 SQL 解析器会忽略 DISTINCT 关键字后面的小括号,而把 DISTINCT 关键字后面的所有列都作为唯一条件 」

我们来看看几个实例

    mysql> SELECT DISTINCT(user) FROM fruits;
    +-------+
    | user  |
    +-------+
    | yufei |
    | hero  |
    +-------+
    2 rows in set (0.06 sec)

当只有一列时有两条记录

    mysql> SELECT DISTINCT(user),fruit FROM fruits;
    +-------+--------+
    | user  | fruit  |
    +-------+--------+
    | yufei | apple  |
    | yufei | banana |
    | yufei | peach  |
    | hero  | apple  |
    | hero  | peach  |
    | hero  | pear   |
    +-------+--------+
    6 rows in set (0.00 sec)

当带括号时,user 列放在括号内,fruit 放在括号外,会发现有五条记录,而 fruit 也参与了唯一条件检查

    mysql> SELECT DISTINCT(fruit),owns FROM fruits;
    +--------+------+
    | fruit  | owns |
    +--------+------+
    | apple  |    3 |
    | banana |    5 |
    | peach  |    3 |
    | pear   |    5 |
    +--------+------+
    4 rows in set (0.02 sec)

当使用 fruit 时就会有 4 条记录 ,因为有两条 apple 3

但是,如果把 fruitowns 都放在括号内,是会报错的

    mysql> SELECT DISTINCT(fruit,owns) FROM fruits;
    ERROR 1241 (21000): Operand should contain 1 column(s)

好诡异,我暂时还想不到如何解释这种结果

SQL DISTINCT 的基本用法

在日常使用 DISTINCT 关键字时,一般有以下几种

注意: 请留意每种的列的数量

  1. 单独获取某一列不重复的值

    这种情况下,有无小括号的结果是一样的

    mysql> SELECT DISTINCT user FROM fruits; +-------+ | user | +-------+ | yufei | | hero | +-------+

    mysql> SELECT DISTINCT(user) FROM fruits; +-------+ | user | +-------+ | yufei | | hero | +-------+

  2. 单独获取某一列不重复值的数量

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

  3. 以多列作为条件获取不同的值

    一定要记住,当你使用多列时,并不仅仅时使用小括号内的列,而是全部列

    mysql> SELECT DISTINCT(user),fruit FROM fruits; +-------+--------+ | user | fruit | +-------+--------+ | yufei | apple | | yufei | banana | | yufei | peach | | hero | apple | | hero | peach | | hero | pear | +-------+--------+

有可能你仅仅时想返回唯一的 user 列然后附带 fruit 列,比如你想要的结果是这样的

    +-------+--------+
    | user  | fruit  |
    +-------+--------+
    | yufei | apple  |
    | hero  | apple  |
    +-------+--------+

单独的 DISTINCT 关键字并不能实现这样的效果,而且也没有任何意义,因为每个 user 都有三条记录,为什么会单独返回 apple ?

如果你真需要这样的结果,有两种方法

  1. 附带 SQL WHERE 子句 子句
        mysql> SELECT DISTINCT(user),fruit FROM fruits WHERE fruit='apple';
        +-------+-------+
        | user  | fruit |
        +-------+-------+
        | yufei | apple |
        | hero  | apple |
        +-------+-------+
在这种语句下,`fruit` 返回的值是固定的
  1. 使用 GROUP BY 子句
        mysql> SELECT DISTINCT(user),fruit FROM fruits GROUP BY user;
        +-------+-------+
        | user  | fruit |
        +-------+-------+
        | hero  | apple |
        | yufei | apple |
        +-------+-------+
这种情况下返回的 `fruit` 是不固定的,虽然,有时候是按照 id 的顺序取值,但并不保障

结束语

只能说,好诡异的 DISTINCT 关键字。使用的时候尽可能的保证列的简单,最好,只使用一列


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] ,回复【面试题】 即可免费领取。

阅读全文