• 最近踩的两条sql的坑


    1.用分类讨论的思想厘清逻辑细节

    给定下边一张学员表student

    idnamenationage
    1张三汉族40
    2李四回族35
    3王五回族37
    4赵六壮族28

    如果要查询小于等于40岁的汉族学员 和 小于等于35岁的回族学员, 那么sql为:

    SELECT
    	* 
    FROM
    	student 
    WHERE
    	( nation = '汉族' AND age <= 40 ) 
    	OR ( nation = '回族' AND age <= 35 );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    而不能写作:

    SELECT
    	* 
    FROM
    	student 
    WHERE 
       nation in ('汉族','回族') 
    	 AND (age <= 40 OR age <= 35) ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我理解,这实际上是数学上的分类讨论思想,一定要对每种情况分别讨论,而不能混为一谈。

    昨天排查一个差异配置的bug搞到半夜,问题就出在了这块的分类讨论逻辑不严谨,sql片段如下:

    	    cdp.param_type in (0,1)
    	    AND (
                cdspi.is_custom = 1
    			OR (
                    cdspi.is_custom = 2
                    AND cds.is_show_general = 1
                )
    		)		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    修正后的样子如下:

     	    cdp.param_type in (0,1)
    	    AND (
    				(
    				  cdp.param_type = 1
    				   AND cdspi.is_custom = 1
    				 )
    			 OR 
    			    ( 
    				 cdp.param_type = 0
                      AND cdspi.is_custom = 2
                      AND cds.is_show_general = 1
                    )
    			)	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.on 和 where 条件的区别

    on 和 where 条件的区别如下:

    on 条件是在生成临时表时使用的条件
    where 条件是在临时表生成好后,再对临时表进行过滤的条件

    tab1

    idsize
    110
    220
    330

    tab2

    sizename
    10AAA
    20BBB
    20CCC

    分析两条sql:

    select * from tab1 
    left join tab2 on (tab1.size = tab2.size) 
    where tab2.name='AAA'
    
    • 1
    • 2
    • 3
    select * from tab1 
    left join tab2 
    on (tab1.size = tab2.size and tab2.name='AAA') 
    
    • 1
    • 2
    • 3

    前者的执行过程是先生成了一张如下的临时表:

    tab1.idtab1.sizetab2.sizetab2.name
    11010AAA
    22020BBB
    22020CCC
    330nullnull

    然后再用tab2.name='AAA’过滤,最终只得到第一条数据

    后者的执行过程是先生成只有一条数据的临时表,然后跟左表进行左关联,得到如下结果

    tab1.idtab1.sizetab2.sizetab2.name
    11010AAA
    220nullnull
    330nullnull
  • 相关阅读:
    11个Redis系列高频面试题,哪些你还不会?
    【768. 最多能完成排序的块 II】
    Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
    ChatGPT全方位解析:如何培养 AI 智能对话技能?
    Java实验七
    TMS Sphinx Alexandria Full Source
    欠拟合和过拟合
    winform车辆管理系统VS开发sqlserver数据库CS结构c#编程源码程序
    Spring学习第5篇:自动注入(autowire)详解
    【数据结构】带头双向链表的简单实现
  • 原文地址:https://blog.csdn.net/wangchenggong1988/article/details/127434266