>>与软件开发有关的知识:操作系统,数据库,网络通信等 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 18154 个阅读者 刷新本主题
 * 贴子主题:  如何成为写SQL高手 回复文章 点赞(0)  收藏  
作者:sunshine    发表时间:2020-07-13 00:41:34     消息  查看  搜索  好友  邮件  复制  引用

    

SQL基础理论知识

掌握基础理论知识是成为SQL高手第一步,我不会照搬教科书式的讲课,我只会讲解我认为你最应该的掌握的3个知识点。

  1、集合(Set)。我给大家一个简单的概念,sql里面一切皆集合。SQL 以关系代数为基础发展出来的一门语言,关系代数主要是“集合”。

sql语句形式:select .... from ....

集合在sql当中的表现形式:每一个select语句都是一个集合,写在from后面的每个表、子查询、视图可以算作一个集合。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

第一种情况

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

第二种情况

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

第三种情况

2、笛卡尔积

  select * from table1,table2,table1存在a列m行,table12存在b列n行,最后形成的集合是(a+b)列,(m*n)行记录。我们学计算机你会发现一个现象,越往前追溯,都会一个简单模型,如果你把所有sql问题往前推,最后都会看到 “笛卡尔积”的身影。

  我举一个简单的例子,SQL理论中会把选取字段这个操作叫作“投影(project) ”。我不知道大家有无想过这个问题,为什么叫“投影"这个概念,而不是叫其他名称,因为任何sql语句其实到最后都是回归一个“笛卡尔积”,你在选取字段操作,好似对“笛卡尔积”做了一次“投影"。

3、集合之间的关系

集合之间的关系 一对一、一对多(最频繁)、多对多(几乎不用),在数据库表中通常用FOREIGN KEY表示一对多的关系 。为什么要关注它们之间的关系,主要写sql的语句发现记录重复现象,你一定要检查是不是一对多,多对多之间的关系。但是当sql语句复杂以后了,即便你分析清楚集合之间的关系,很可能出现记录重复的现象,当与你的预期不符,我们可以distinct去重。

五、SQL中实战技巧

  这次我不再分析如何去书写一个sql语句,我相信大家多多少少会写sql。我只是跟大家分享一下我掌握的技巧。

1、能少写,就不要多写(write less,do more)。为什么要这样,第一个提高效率;第二个减少出错几率。举例说明:假设我们写内连接语句。其实是有2种写法,我推荐大家使用第一种写法。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

          特别注意在oracle数据库当中,左连接、右连接有一种简写的方式。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

            2、为什么有时候别名需要增加双引号。当你的别名,包含特殊符号的时候,就要增加双引号,比如+、-、*、/、(、)。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

          3、使用null注意事项。null指的是理论意义上的绝对的空,不指任何含义。所以空字串、空数组、空对象表示含义的空,不是null。所以null一般使用身份运算符 is,以示区分,is null或者is not null。像python是用is判断,但是java,js中用==来判断,有些编程语言对这个问题并没有严格区分。

4、union 和union all之间的区别。union将两个集合去掉重复记录合并在一起,union all只是简单合并在一起。

5、group by使用问题。有时候会发现聚合函数,感觉数值明显错误,先去掉group by 查看原始记录,看where条件是否写错。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

          6、充分利用数据库提供函数,简化sql书写难度。举例说明:同时统计采购物品A、B、C、D分类的小计

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

          同时统计某个科室的出库给中心药房的基数、节约的小计。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

                     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

          当然我不可能穷举所有的技巧,我只是把我使用最多一些技巧分享给大家,精通sql需要大家长期实践。

案例分析

  我曾经收到来自基层医疗机构的多位小伙伴的求助,他们在写sql的时候出现“卡壳”问题。其实不管使用oracle、mssql、mysql解决问题的原理思路都是一样,只不过表现形式不同。以下分享协助小伙伴处理问题2个案例。

案例一:某小伙伴遇到数据上报问题,某个药品入库与出库数据需要在同一行展示,因为“入库与出库”来源于不同的表,小伙伴用了一种最原始的方法来处理。小伙伴的解决方案,把“入库数据”统计出来放入一个中间表,把“出库数据”统计出来放入一个中间表,再将两个中间表关联查询。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

入库

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

出库

小伙伴感觉这样处理比较麻烦,期望能用一条sql语句解决问题。我帮小伙伴分析是否可以用一条sql搞定的可能性,第一,对于来自于不同来源数据“入库”和“出库”,相当于不同的集合,可以使用union连起来;第二,union合并有个特点,要求两个集合是相同字段类型,相同的字段的个数,缺少的字段可以使用虚拟列来解决;第三,将union结果当作子查询(相当于得到一个新的集合),再进行group by处理,可以完成整个操作。 最终sql语句部份截图如下所示:

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

入库补充虚拟列

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

出库补充虚拟列

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

union当作子查询再进行group by

案例二:某小伙伴,制作检验视图给第三方调用,当某个检验结果,超过了正常范围,显示↑,↓,否则为空,如下图所示。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

需求

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

使用case when

  小伙伴在百度搜寻很多资料或许也是看了我的文章,想到了可以用case when来解决这个问题,但是执行过程中报“sql server 从数据类型varchar 转换为 float时出错”。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

出错信息

因为我对mssql不熟悉这个问题对于我来说还是有一点的难度。我的思考过程如下,既然是数据类型出错,ISNUMERIC(b.lac13) > 0,这个条件嫌疑就很大,isnumeric没有真正把“数字值”过滤干净,我百度一下isnumeric返回值,只有两个返回值1,0。我当时敏锐感觉到问题就在这里,ISNUMERIC(b.lac13) > 0这种写法本身就是一个“坑”,假设判断ISNUMERIC(‘阴性’) 返回0,0>0就成立,convert去转换的时候就会报“sql server 从数据类型varchar 转换为 float时出错”。

我叫小伙伴改成ISNUMERIC(b.lac13)? and CONVERT(float, b.LAC10) < CONVERT(float, b.lac13),再测试,果然问题就解决了。1代表true,0代表false这个习惯是从C语言那里继承过来的。不过小伙伴有点担心,如果ISNUMERIC(‘阴性’)? and CONVERT(float, ‘阴性’) 这样判断不是一样有问题吗?我了解小伙伴这个担心,如果他掌握一个基础知识,这种担心是完全是多余的。什么意思,一般编程语言都会有一个if条件熔断机制。举例说明:条件1 and 条件2 and 条件3,假设条件1是false,就可以决定整个表达式的值,意味着条件2 , 条件3不会再去做判断处理,就好像发生了“熔断”。再比如:条件1 or 条件2 or 条件3,假设条件1是true,就可以决定整个表达式的值,意味着条件2 , 条件3不会再去做判断处理。

  如果小伙伴还是不放心,可以将条件改成ISNUMERIC(b.lac13) == 1,就不会存在理解不了这个问题了。

           点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

处理效果

总结

  俗说“光说不练假把式”。多写sql才能掌握真技术,同时也要不停的跳出自己的“舒适区”。为什么有人干了10年,水平还是很菜,因为他只不过把有些事情重复干了10年而己,并没有真的成长。每次写sql的时候,能不能不用中间表、能不能再简单一点,每次挑战一下自己,完成同样的效果。所谓的高手,大部分都在挑战自己能力边界。最后祝大家都从文中有所收获,成为sql高手!

----------------------------
原文链接:https://www.jianshu.com/p/5c6305c9c099

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-10-23 09:38:04 重新编辑]
  Java面向对象编程-->Java注解
  JavaWeb开发-->使用Session(Ⅰ)
  JSP与Hibernate开发-->映射组成关系
  Java网络编程-->用Swing组件展示HTML文档
  精通Spring-->绑定CSS样式
  Vue3开发-->组合(Composition)API
  我必须得告诉大家的MySQL优化原理
  服务器排障 之 nginx 499 错误的解决
  Linux文件系统误装入到Ocfs2文件系统的数据卷上的解决过程
  MySQL的所有函数的用法
  MySQL ALTER命令
  SQL CREATE VIEW、REPLACE VIEW、 DROP VIEW 语句
  SQL UNIQUE 约束
  SQL NOT NULL 约束
  SQL SELECT INTO 语句
  SQL FULL OUTER JOIN 关键字
  Windows 和 Mac的键盘快捷键汇总
  XML的DTD定义
  Service Mesh 落地负责人亲述:蚂蚁金服双十一四大考题
  MySQL的实现定时执行任务的存储过程
  开发好几年,你真的懂MQ嘛(RabbitMQ为例)?看完别说难搞哦
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。