V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
JJstyle
V2EX  ›  MySQL

面试了几个程序员,发现他们对于 mysql 的 distinct 关键字都存在错误的理解

  •  4
     
  •   JJstyle · 2020-07-20 16:01:24 +08:00 · 7710 次点击
    这是一个创建于 1586 天前的主题,其中的信息可能已经有所发展或是发生改变。

    都认为这是一个函数,可以这样用:

    select distinct(name), age from test;
    

    目的是给 name 去重。虽然没有报错,但是其实上面的 sql 最终被解析成:

    select distinct (name), age from test;
    

    就是说 distinct 不是一个函数,而是 select 的一部分,结果是给 name,age 的组合数据去重,name 加括号在这里没有什么意义。

    是那种工作了 3~5 年工作经验的,不知道 v 友们又没有发现这个问题。

    第 1 条附言  ·  2020-07-21 09:22:55 +08:00
    我也只是挑了 sql 中的几个关键字问了一下,v 友们说的对,这种问题遇到了就知道,没遇到也没什么,distinct 一般也只和 count 结合使用。
    42 条回复    2020-08-05 21:52:43 +08:00
    mightofcode
        1
    mightofcode  
       2020-07-20 16:03:54 +08:00
    学到了学到了
    yishengyongyi
        2
    yishengyongyi  
       2020-07-20 16:04:41 +08:00
    踩过这个坑
    achira
        3
    achira  
       2020-07-20 16:07:00 +08:00   ❤️ 1
    前段时间在公司写 sql 发现了,和 select 的选取字段去重无关。是整体去重。实习生。
    XGF
        4
    XGF  
       2020-07-20 16:08:32 +08:00   ❤️ 1
    难怪查询语句美化的时候 distinct 和 select 是同一行。
    当然我写的时候没加括号,也认为是给 name 去重(捂脸)
    学到了,学到了
    Xusually
        5
    Xusually  
       2020-07-20 16:09:20 +08:00
    嗯 需要单列去重,但是要读取多列的用 group by
    gimp
        6
    gimp  
       2020-07-20 16:13:04 +08:00
    哈哈,这题我会。
    yuk1no
        7
    yuk1no  
       2020-07-20 16:16:56 +08:00 via iPhone   ❤️ 2
    弄不清的可能没怎么学过 SQL
    如果 distinct 是单列聚合,其余的列怎么处理?
    allAboutDbmss
        8
    allAboutDbmss  
       2020-07-20 16:21:25 +08:00
    我做了一个很小的例子 用的是 PosgreSQL
    ```
    psql=# with test (a, b) as ( VALUES (1, 2), (1, 4), (1, 3) ) select distinct(t.a), t.b from test t;
    a | b
    ---+---
    1 | 3
    1 | 2
    1 | 4
    (3 rows)

    psql=# explain with test (a, b) as ( VALUES (1, 2), (1, 4), (1, 3) ) select distinct(t.a), t.b from test t;
    QUERY PLAN
    ---------------------------------------------------------------------
    HashAggregate (cost=0.11..0.14 rows=3 width=8)
    Group Key: t.a, t.b
    CTE test
    -> Values Scan on "*VALUES*" (cost=0.00..0.04 rows=3 width=8)
    -> CTE Scan on test t (cost=0.00..0.06 rows=3 width=8)
    (5 rows)
    ```
    outerws
        9
    outerws  
       2020-07-20 17:02:51 +08:00
    @yuk1no 可以用 group by 替代
    windyboy
        10
    windyboy  
       2020-07-20 17:08:15 +08:00   ❤️ 2
    有的时候考知识点并不是很好的方案
    毕竟有可能没有遇到过
    但并不和能力有直接关联
    toyassb
        11
    toyassb  
       2020-07-20 17:21:18 +08:00 via iPhone
    呃,看这个第一反应是 sql 还能这么写
    javlib
        12
    javlib  
       2020-07-20 17:29:24 +08:00
    @allAboutDbmss 所以从 explain,可以看到 group 是对 t.a, t.b 两个字段一起做 group 。
    还有就是 with 可以这样用,学到了,谢谢
    krixaar
        13
    krixaar  
       2020-07-20 17:31:29 +08:00
    distinct 能这样用的话光语义上都解释不了,name 相同但 age 不同的行只挑其中一个?随机挑?按顺序挑?按什么顺序?
    zppass
        14
    zppass  
       2020-07-20 17:35:29 +08:00
    这种 distinct 一般来说就是单独使用,算个数的话会使用。一般来说像聚合查找的话就是用 group by 来就满足要求了。
    dongisking
        15
    dongisking  
       2020-07-20 17:36:37 +08:00
    好奇 lz 是怎么找到答案的
    aguesuka
        16
    aguesuka  
       2020-07-20 17:37:49 +08:00 via Android
    7 楼才是正确思路。"是什么"而不是"为什么",比起什么都不知道,不过是多踩一个坑罢了
    HankAviator
        17
    HankAviator  
       2020-07-20 17:51:09 +08:00 via Android
    @zppass 感觉 distinct 比 group by 资源消耗更大一点
    gz911122
        18
    gz911122  
       2020-07-20 18:00:41 +08:00   ❤️ 2
    卧槽那是有多菜
    j0hnj
        19
    j0hnj  
       2020-07-20 18:03:19 +08:00
    distinct 与聚合函数一起使用的场景更常见一些,比如 select count(distinct name), select group_concat(distinct score)
    lovecy
        20
    lovecy  
       2020-07-20 18:06:32 +08:00
    distinct 感觉是出查询结果后再扫描查询结果去重的,`SELECT DISTINCT 字段 FROM 表;`如果字段没有索引就会全表扫描,我的理解就到这里了。。
    raaaaaar
        21
    raaaaaar  
       2020-07-20 18:09:49 +08:00 via Android   ❤️ 3
    比较赞同,“是什么”的知识更多的是考察经验,能解释“为什么”的知识才是重点,后者还能考察应试者的思路
    NetCobra
        22
    NetCobra  
       2020-07-20 18:26:37 +08:00
    从来没有这么用过,意思上也解释不通。
    只给 name 去重不应该是 group by 吗?
    fhsan
        23
    fhsan  
       2020-07-20 18:34:23 +08:00
    我都是 group by,其实你这是考察一条 SQL 执行到底发生了什么
    Still4
        24
    Still4  
       2020-07-20 18:47:06 +08:00
    没这么用过肯定不知道的,也就是说相当于
    ```
    select name,age from test group by name,age;
    ```
    lxk11153
        25
    lxk11153  
       2020-07-20 18:54:13 +08:00
    select name,age from test group by name,age;
    select distinct name,age from test ;
    有性能,或者内存占用,等等差异吗?求解
    zsdroid
        26
    zsdroid  
       2020-07-20 18:55:09 +08:00
    百度+bing 搜索 distinct,排第一的都是 w3school
    https://www.w3school.com.cn/sql/sql_distinct.asp
    该教程里只用了一个字段来做演示,有一定的误导性,让看的人以为这是针对某个字段的。
    wshcdr
        27
    wshcdr  
       2020-07-20 20:24:15 +08:00
    w3school 的教程有点一言难尽
    chaffy
        28
    chaffy  
       2020-07-20 20:29:27 +08:00
    学习了学习了
    Egfly
        29
    Egfly  
       2020-07-20 20:41:05 +08:00 via iPhone
    估计是没系统学过 mysql,不然不可能不知道这个
    hheedat
        30
    hheedat  
       2020-07-20 20:42:51 +08:00
    工作六年,没用过 distinct ... 学习了
    Chieh
        31
    Chieh  
       2020-07-20 20:59:42 +08:00
    蛤?怎么会是函数 distinct 只能和 select 一起用,我一直当作是 select 的另一个版本
    talen666
        32
    talen666  
       2020-07-20 22:10:27 +08:00
    (・。・)虽然用的少,但知道是个关键字,不是函数
    Justin13
        33
    Justin13  
       2020-07-20 22:12:39 +08:00 via Android
    <query spec> ::= SELECT [ ALL | DISTINCT ] <select list> <table expression>
    walkerliu
        34
    walkerliu  
       2020-07-20 22:19:13 +08:00
    这种题问我虽然我能答的上来,但我觉得这种题目是问不出一个人的真实水平的
    l00t
        35
    l00t  
       2020-07-20 22:22:13 +08:00
    居然还能理解成只去重一个字段的函数?从知道这个 distinct 开始就从没那样理解过,句意上都不通啊……
    jun0205
        36
    jun0205  
       2020-07-20 23:18:36 +08:00
    这种面试能考啥,这样去重应该用 group by 的居多。
    你这算是自己设计的一个坑,大部分人用也不会这样用,文档语法也没有这种,也就不会遇不到这个坑。
    Narcissu5
        37
    Narcissu5  
       2020-07-21 09:30:13 +08:00
    @yuk1no 实际上 group 也有这种的问题,聚合条件之外的列怎么处理,sqlserver,oracle 里面这样的列不带聚合函数就会报错

    但是 mysql 是可以正常工作的,是的,mysql 就是这样一种神奇的数据库。所以在 mysql 里面即使认为是单列聚合也没什么说不通的
    yuwangG
        38
    yuwangG  
       2020-07-21 10:17:29 +08:00
    学到了~
    aguesuka
        39
    aguesuka  
       2020-07-21 12:37:34 +08:00 via Android
    @Narcissu5 没开严格模式
    leonardyang
        40
    leonardyang  
       2020-07-21 16:56:43 +08:00
    我记得 distinct 在 oracle 和 sqlserver 的语法树上是关键字吧,肯定不是函数
    dingyaguang117
        41
    dingyaguang117  
       2020-07-21 22:51:14 +08:00
    能写出这种 SQL, 本身思维就不严谨
    daimubai
        42
    daimubai  
       2020-08-05 21:52:43 +08:00
    distinct 不是函数,它是对查询的所有字段去重
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3013 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:48 · PVG 18:48 · LAX 02:48 · JFK 05:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.