V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
einQimiaozi
V2EX  ›  程序员

为什么 mysql 要搞出 having where on 三个关键字?

  •  1
     
  •   einQimiaozi ·
    einQimiaozi · 2021-06-13 16:35:39 +08:00 · 4974 次点击
    这是一个创建于 1254 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我感觉完全没必要啊,只保留一个 where 然后直接按照 sql 语句的书写顺序决定限制条件和临时数据表是否生成何时生成不就好了吗?为什么要设计三个关键字?
    32 条回复    2021-06-16 16:34:24 +08:00
    Boyce
        1
    Boyce  
       2021-06-13 17:10:46 +08:00
    on 不是 join 的配套语法吗,去了 on 功能缺失啊。
    waytoshine
        2
    waytoshine  
       2021-06-13 17:29:24 +08:00 via iPhone   ❤️ 14
    幸好帖子不能删
    felixin
        3
    felixin  
       2021-06-13 17:45:55 +08:00 via Android
    这就和 c 语言不需要花括号一样是冗余的语法设计
    zlowly
        4
    zlowly  
       2021-06-13 17:46:51 +08:00   ❤️ 1
    而且 having 里的条件是针对的 group 的,和 where 完全不一样。
    如果你没分清两者区别,无意冒犯,但建议还是认真系统的学习一下基础 SQL 。
    另外这个也不是 mysql 高出来的,这个是 ANSI SQL 标准语言。
    Cbdy
        5
    Cbdy  
       2021-06-13 18:02:39 +08:00 via Android
    可以找本书系统学习一下
    gjquoiai
        6
    gjquoiai  
       2021-06-13 18:13:50 +08:00
    这也不是冗余设计
    on 和 where 只有 inner join 这一种情况下才能称得上“表现一样”;
    where 和 having 完全不一样。
    mainjzb
        7
    mainjzb  
       2021-06-13 18:29:52 +08:00   ❤️ 1
    。。。一个复杂的 sql 语句,我第一眼直接找 ON 就好了。为什么要去找到好几个 WHERE 然后脑力分析和 JION 匹配的 WHERE ?
    你这样的设计是为了简化关键词记忆? 这反而导致了难用至极的阅读和分析(如果有 IED 能颜色区分也许还行,远古时期更是没有颜色高亮编码时代,进一步说书本也难以每本都高亮颜色来区分)
    光靠肉眼来找,哪个是和 JION 相连的 WHERE,可见楼主没有写见过多 SQL, 难用的糟糕程度可以参见三元运算符的套娃

    一个例子是 go 取消了 C++那一套的-> 和. 的区别,单纯使用. 来进行函数调用,这个简化了开发者的编写负担,弱化了指针的概念,让开发者可以更简单的进行开发。因为我们要就是要调用函数,不需要关心变量到底是指针还是实例,这不重要,所以我们简化了。
    但是替换 WHERE 显然没有这样的效果,反而会增加阅读困难,(就像很多人吐槽 go 一堆圆括号漫天飞增加了阅读难度一样,其实个人感觉还好并没有太糟糕)楼主这种激进的概念,就像想要把所有花括号换成圆括号一样。严重增加阅读难度,是个反面教材。
    einQimiaozi
        8
    einQimiaozi  
    OP
       2021-06-13 18:31:41 +08:00
    @zlowly 这个我知道,我的意思是为什么要专门设计一个 having 或者 on,比如我在 group by 后面接 where,正常逻辑肯定是希望先 group by 根据分组结果再进行过滤吧,那为什么还要设计一个 having ?直接通过书写顺序判断不就可以了吗
    einQimiaozi
        9
    einQimiaozi  
    OP
       2021-06-13 18:49:35 +08:00
    @gjquoiai 所以我说了书写顺序啊,having,where 和 on 的最大区别不就是联合查询和聚合顺序的区别么,按照书写顺序判断不就可以只用一个关键字了么,毕竟正常人如果想先分组再过滤,不会在书写的时候故意把过滤写在分组之前吧
    lance6716
        10
    lance6716  
       2021-06-13 18:51:30 +08:00 via Android
    @einQimiaozi 可以试试自己改一下 parser,看看有没有冲突吧
    thunderw
        11
    thunderw  
       2021-06-13 18:53:03 +08:00   ❤️ 1
    这是不赖 MySql,它只是个随波逐流的。你得去跟制订 SQL 标准的大佬们杠一下才行😂。
    WHERE 做 JOIN 是 ANSI SQL-89 implicit syntax 。
    JOIN 做 JOIN 是 SQL-92 才引入的「新」语法 ANSI SQL-92 explicit join syntax 。目的是为了提高可读性。
    HAVING 则完全不是一回事。WHERE 和 JOIN 是在 GROUP 前发生的,HAVING 则是在 GROUP 之后发生的。
    Lemeng
        12
    Lemeng  
       2021-06-13 18:54:50 +08:00
    肯定不是冗余了写多了就了解奥妙了
    einQimiaozi
        13
    einQimiaozi  
    OP
       2021-06-13 18:57:23 +08:00
    @thunderw 顺序问题我知道,我的意思是 having 本来就在 group by 之后,假设没有 having 关键字,只有 where,正常情况下如果希望 gourp by 后进行过滤,没人会把 where 写在 group by 之前吧,那 having 还有什么存在的意义么
    Cbdy
        14
    Cbdy  
       2021-06-13 19:25:34 +08:00   ❤️ 4
    HAVING and WHERE are often confused by beginners, but they serve different purposes. WHERE is taken into account at an earlier stage of a query execution, filtering the rows read from the tables. If a query contains GROUP BY, data from the tables are grouped and aggregated. After the aggregating operation, HAVING is applied, filtering out the rows that don't match the specified conditions. Therefore, WHERE applies to data read from tables, and HAVING should only apply to aggregated data, which are not known in the initial stage of a query.

    To view the present condition formed by the GROUP BY clause, the HAVING clause is used.

    ---

    当然,如果你一定都要“复用”WHERE 这个关键词也可以(万物皆虚,万物皆允,你可以设计一个基于“喵喵喵”关键词的的结构化查询语言),通过上下文来决定的“WHERE”的含义,这个是设计的问题,而我不认为这是一个好的设计
    thunderw
        15
    thunderw  
       2021-06-13 19:38:31 +08:00   ❤️ 3
    @einQimiaozi 明明不是一样的意思,非要用同一个单词。不是写的人痛苦,读的人痛苦,做编译器的人更痛苦么😂
    SELECT A.x, B.y, COUNT(B.key)
    FROM A LEFT JOIN B
    WHERE A.id=B.id
    WHERE A.name LIKE 'ABC%'
    GROUP BY A.x, B.y
    WHERE SUM(B.v) > 80

    你觉得好看吗……
    yjxjn
        16
    yjxjn  
       2021-06-13 19:41:44 +08:00
    推荐看看《 SQL 必知必会》
    JJstyle
        17
    JJstyle  
       2021-06-13 19:54:26 +08:00 via iPhone
    源领域
    JJstyle
        18
    JJstyle  
       2021-06-13 19:58:44 +08:00 via iPhone
    @thunderw 赞同你的看法,(在如果 lz 了解三者的先后顺序的情况下),确实只是为了增加辨识度、减轻解析压力。
    JJstyle
        19
    JJstyle  
       2021-06-13 20:07:00 +08:00 via iPhone
    就像喝红酒用高脚杯、喝白酒用盏子、喝啤酒用大杯,但是你用大杯喝白酒行不行,当然可以的,这些都是人为定义的标准,除非你能定个标准说咱以后喝啤酒都用盏子并且大家都遵循这个标准。
    c6h6benzene
        20
    c6h6benzene  
       2021-06-13 20:39:49 +08:00 via iPhone
    @einQimiaozi 因为大概只有 MySQL 支持用 group by 和 Having 来“过滤”吧。T-SQL 看到 group by 一定要去找聚合函数的。
    uselessVisitor
        21
    uselessVisitor  
       2021-06-13 21:30:58 +08:00   ❤️ 2
    where 是对分组前进行过滤的,having 是分组后过滤的
    @einQimiaozi #13
    adoal
        22
    adoal  
       2021-06-13 22:42:36 +08:00 via iPhone
    SQL 各种成分的书写位置是固定的,不可能根据一个条件子句的位置判断是用来做聚合前过滤还是聚合后过滤。
    这张设计是为啥就不可考了,也许为了 parse 方便。不过 SQL 的语法确实槽点满满。也有人设计了语义贺和 SQL 一样但语法不一样的查询语言,但这样的改变并不是实质性的,一点点语法糖终究抵不过 SQL 的既成影响力。
    akira
        23
    akira  
       2021-06-13 23:44:48 +08:00
    问就是历史原因
    blockmin
        24
    blockmin  
       2021-06-14 07:08:16 +08:00
    举个不恰当的例子。就好比一个刚学乘法的人吐槽为什么会有乘法这个东西,多加几遍不就行了?不知道以后会遇到几千几万相乘。
    楼主大概没见过一个 sql 语句有两三页 word 那么长的
    shakoon
        25
    shakoon  
       2021-06-14 07:17:50 +08:00 via Android
    你觉得没有必要,是因为你还没有入门。等你多看看别人的代码,就能了解为什么会有这些关键字了。另外,这是标准 sql 语言的语法,不是 mysql 独有的,所有数据库都支持。
    polyang
        26
    polyang  
       2021-06-14 10:50:38 +08:00
    @blockmin 顶一个,说的有道理,这个例子举的不错。
    有了 having,起码能方便我们理解 SQL 吧,看一个 SQL 可以直接找 having 关键字就可以了,去掉了 having,你还得捋一下 SQL 的顺序,虽然简单的 SQL 没什么,但如果是复杂的 SQL 呢?
    paragon
        27
    paragon  
       2021-06-14 11:14:45 +08:00
    模型是基于关系代数的~ 你说没用 那么请用数学方式证明~
    Warder
        28
    Warder  
       2021-06-14 16:00:18 +08:00 via Android
    这是 sql 的语法,又不是 mysql 独有的
    aguesuka
        29
    aguesuka  
       2021-06-14 19:18:26 +08:00
    因为 sql 是上个世 1970 年诞生的, 甚至早于罗素类型论的提出, 而 c 语言是 1972 年诞生的. 也许那个年代没有代码提示, 类型安全, 元编程的概念, 或者不重要. 反例是现代的 nosql 查询.
    aguesuka
        30
    aguesuka  
       2021-06-14 19:37:44 +08:00
    在 V2EX 问 pl 有关的问题, 最好带上 curd boy 不懂的词汇, 比如这个问题可以换成 "为什么 sql 没有 pipeline 查询" 或者 "sql 中的 functor". 也许没有价值的回复会少一点.
    SmiteChow
        31
    SmiteChow  
       2021-06-15 10:54:48 +08:00
    #30 妙啊
    zhangchongjie
        32
    zhangchongjie  
       2021-06-16 16:34:24 +08:00
    这和 mysql 有啥关系? mysql 躺枪
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5602 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 08:42 · PVG 16:42 · LAX 00:42 · JFK 03:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.