sql server numeric 可存几位小数_想成为优秀SQL高手?你就差这些细节
標準結構化查詢語言(Structured Query Language)簡稱SQL,sql是我們日常工作中使用最多一項技能,寫sql可以說是一個可以干到退休的技能??此坪唵?#xff0c;但要精通卻很難。 sql包括增、刪、改、查,創建表、刪除表、修改表等等內容,我們今天所講的sql是一種狹義上select語句,這個使用最頻繁,也是最復雜的。寫一篇關于技術類的文章,既要深刻,又要通俗易懂,的確要耗費我不少精力,如果大家覺得此文對你或者有需要的人有所幫助,整理不易,記得關注小編 歡迎您轉發!
一、sql會不會淘汰?
大家滿懷熱情點進來學習一下sql,首先要搞清楚一個問題,sql會淘汰嗎?要回答這個問題,首先有必要了解sql發展背景,它是關系型數據庫誕生的產物,有時候不得不佩服這些先輩,當關系型數據庫起步發展的時候,就制定了一個統一的操作標準,就是SQL標準,所有關系型數據庫(mysql/mssql/oracle)都會實現這個標準,這也是為什么sql會長盛不衰的原因,所以sql會不會淘汰,要看關系型數據庫會不會淘汰?到目前為止沒有看到任何關系型數據庫淘汰的跡象,傳統關系型數據庫過渡到分布式關系型數據庫,這是未來極有可能發生的事。
你可能會問市面不是有一個nosql的東西?首先nosql翻譯成中文,不是”沒有sql“的意思,而是”不僅僅有sql,還有其它“,nosql是not only sql的簡稱。nosql說的一種補充,什么意思,sql主要處理結構化的數據,nosql主要處理非結構化的數據。目前來說nosql沒有一個統一的標準,都是按照用途來發展,比如鍵值(Key-Value)存儲數據庫, Redis;列存儲數據庫,Cassandra;文檔型數據庫, MongoDb;圖形(Graph)數據庫,Neo4J。
二、什么是IT高手
扎實理論基礎知識,這是決定一個人水平飛得有多高。靈活運用這個基礎知識(非常難),才決定一個人水平有多牛。為什么我會說經常出現”卡殼“現象,有些看上去很難的問題,其實運用一些基礎知識就可以解決,但是要做這一點非常困難。
我們通常對高手定義都是可以處理日常工作中一些難題,注意我說的是一些難題,不要期望解決所有的難題,什么是日常工作的難題?特點一:問題偶然出現,無法重現問題;特點二,沒有明顯的邏輯錯誤,沒有解決問題思路;特點三:問題本身就很難(比如數據結構與算法)。比如,我們HIS里面醫技系統就有這樣一個難題一直無法解決,護士錄入A代碼記錄,后臺偶然間會保存B代碼記錄,半年時間偶然出現1,2次,但是我們在HIS程序里面各種極端操作測試,始終無法重現問題,實在令人不解!
在這里我分享一下曾經處理過難題,你會驚訝的發現,解決問題的方法很簡單,都是用的最基本的基礎知識解決的,但是你想到這種解決方法,非常不易!
第一個問題:使用netbeans開發環境,在書寫js函數queryStr的時候,按ctrl+shift+F格式化代碼的時候,偶然會出現結構混亂,有時候發現導航器js未出現這個函數,如下圖所示:
問題原因: 原來js代碼與html在同一個文件來寫的,原來在queryStr函數是包含動態生成html代碼的片斷,雖然這個代碼放變量賦值里面,在格式化的時候,netbeans依然會檢測這個html是否合法,導致縮進混亂,和導航器分析不出這個函數。我個人猜測格式化的底層實現,將整個文檔解析,解析html標簽,即便html標簽寫在js字符串變量里面,如果沒有完整配對,依然會出問題。
解決方法:保證queryStr涉及的html字符完整,并且里面提及的函數必須聲明出來。
第二個問題:下面來分享mysql bug。通過mysqldump導出來sql腳本,測試還原過程中,出現[Err] 1064錯誤,跟蹤到是以下語句出錯,百思不得其解,當時寫進數據庫沒有任何問題,為什么導出來,再導進去的時候就報錯。
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''
質控科劉成章要求統計2018.04.01---2018-06-30門診醫生的收' at line 9
可能存在的原因:
UPDATE `info`.`fh_comm_detail` set `cl_proc` = ‘.....’ WHERE (`mxid` = '100005')
cl_proc后面的值當中包含/*,*/注釋符號,mysql去解析的時候,觸發bug,原本包含在‘’中字符串含義發生變化,導致語句報錯。(但是我在mysql查詢分析器,怎么樣都模擬不出來這種錯誤,就是偶然發生)。
解決方法:將/*注釋符號替換為其他字符即可,比如”--”,讓其不觸發解析注釋串。
問題三:聯網醫保金額與本地程序計算,有少數患者偶爾會存在金額不一致問題。翻看程序代碼左看右看,都沒有問題,如下所示。
lc_jine_sum = round(tab_1.tabpage_1.dw_1.getitemnumber(1,"jine_total"),2)
問題原因:我突然想起一個基礎知識,計算機浮點數本身是不準確的,每次運算都有可能得出不同的結果,既然不準確,為什么我們還會大規模使用計算機來解決問題,解決方法就是提高計算機處理精度,讓它無限逼近準確。什么意思,我們大部分現實當中,大部分都是計算到2位小數,最多也是4位小數,但是計算機就無所謂,10-20位都可以處理,10-20位小數精度再截取2-4位小數,當然就可以做到準確無誤。大家是否遇到過這種問題,明明只有一位小數,把這些數字加起來的時候,你會看到一長串小數,這就是計算機內部使用高精度計算的問題,如下圖所示。
計算機內部使用高精度的小數(一般是10幾位以上),來解決小數不準確的問題。所以我當時就把代碼改了一下,果然改完以后,問題從此沒有出現過。這就是利用基礎知識去解決實際當中的難題,你看得我寫的很簡單,其實想到這個方法是非常困難的。
lc_jine_sum =round(tab_1.tabpage_1.dw_1.getitemnumber(1,"jine_total"),4) //先取出 4 位小數
lc_jine_sum = round(lc_jine_sum,2) //再進行 2 位小數四舍五入
三、解決一個sql問題基本思路
日常工作sql語句主要用途,臨時統計數據、后臺查數找問題原因、制作報表。拿到一個sql語句的問題首先我們先從業務角度分析,后臺是否存在數據,它們是否存在相應關聯?沒有數據,沒有關聯,后繼工作毫無意義。
舉例說明,患者用藥追蹤,統計患者用了哪個廠家哪個批次的藥品。統計的意義,如果發藥哪個批次有問題,可以精準找到相關患者。第一個問題,后臺有數據嗎,有的。his里面基本上都有藥品出入庫、患者用藥數據,但是藥品管理的廠家、批次,與患者用藥之間沒有關聯。這也是his系統里面的一個難題,目前我還沒有看到靠譜的解決方案。由上述可以得知,患者用藥追蹤,這個問題無法用sql解決。
其次,通常你拿到一個稍微復雜sql問題一般不能一步到位寫出來。別操之過急,學會化解問題。舉例說明,統計歷史連續某段時間內每日在院人數,假設his系統中沒有生成數據(每天將在院人數數據拷貝生成一個中間表數據)。
第一步分解:假設你現在統計歷史某日(2020-03-01)的在院人數,在院人數 = (入院日期 <= 在院人數 <= 出院日期) + 一直未出院的在院人數。
第二步分解:模擬生成連續某段時間,比如2020-03月份,再關聯生成每日在院人數
最后,需要驗證統計出來的數據是否正確,經過驗證,統計出來的歷史在院數據是完全正確的,發現有個別出現1,2個人的誤差,是因為人為修改了”入院日期“,”出院日期“所致,如果你想檢驗sql水平怎么樣,我給你一個判斷標準,是否使用了中間表。嚴格來說,只要數據庫存在數據,存在關聯,就可以用sql語句查出來,如果你精通sql是不會用到中間表的。
四、SQL基礎理論知識
掌握基礎理論知識是成為SQL高手第一步,我不會照搬教科書式的講課,我只會講解我認為你最應該的掌握的3個知識點。
1、集合(Set)。我給大家一個簡單的概念,sql里面一切皆集合。SQL 以關系代數為基礎發展出來的一門語言,關系代數主要是“集合”。
sql語句形式:select .... from ....
集合在sql當中的表現形式:每一個select語句都是一個集合,寫在from后面的每個表、子查詢、視圖可以算作一個集合。
第一種情況
第二種情況
第三種情況
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種寫法,我推薦大家使用第一種寫法。
特別注意在oracle數據庫當中,左連接、右連接有一種簡寫的方式。
2、為什么有時候別名需要增加雙引號。當你的別名,包含特殊符號的時候,就要增加雙引號,比如+、-、*、/、(、)。
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條件是否寫錯。
6、充分利用數據庫提供函數,簡化sql書寫難度。舉例說明:同時統計采購物品A、B、C、D分類的小計
同時統計某個科室的出庫給中心藥房的基數、節約的小計。
當然我不可能窮舉所有的技巧,我只是把我使用最多一些技巧分享給大家,精通sql需要大家長期實踐。
六、案例分析
我曾經收到來自基層醫療機構的多位小伙伴的求助,他們在寫sql的時候出現“卡殼”問題。其實不管使用oracle、mssql、mysql解決問題的原理思路都是一樣,只不過表現形式不同。以下分享協助小伙伴處理問題2個案例。
案例一:某小伙伴遇到數據上報問題,某個藥品入庫與出庫數據需要在同一行展示,因為“入庫與出庫”來源于不同的表,小伙伴用了一種最原始的方法來處理。小伙伴的解決方案,把“入庫數據”統計出來放入一個中間表,把“出庫數據”統計出來放入一個中間表,再將兩個中間表關聯查詢。
入庫
出庫
小伙伴感覺這樣處理比較麻煩,期望能用一條sql語句解決問題。我幫小伙伴分析是否可以用一條sql搞定的可能性,第一,對于來自于不同來源數據“入庫”和“出庫”,相當于不同的集合,可以使用union連起來;第二,union合并有個特點,要求兩個集合是相同字段類型,相同的字段的個數,缺少的字段可以使用虛擬列來解決;第三,將union結果當作子查詢(相當于得到一個新的集合),再進行group by處理,可以完成整個操作。 最終sql語句部分截圖如下所示:
入庫補充虛擬列
出庫補充虛擬列
union當作子查詢再進行group by
案例二:某小伙伴,制作檢驗視圖給第三方調用,當某個檢驗結果,超過了正常范圍,顯示↑,↓,否則為空,如下圖所示。
需求
使用case when
小伙伴在百度搜尋很多資料或許也是看了我的文章,想到了可以用case when來解決這個問題,但是執行過程中報“sql server 從數據類型varchar 轉換為 float時出錯”。
出錯信息
因為我對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,就不會存在理解不了這個問題了。
處理效果
七、總結
俗說“光說不練假把式”。多寫sql才能掌握真技術,同時也要不停的跳出自己的“舒適區”。為什么有人干了10年,水平還是很菜,因為他只不過把有些事情重復干了10年而己,并沒有真的成長。每次寫sql的時候,能不能不用中間表、能不能再簡單一點,每次挑戰一下自己,完成同樣的效果。所謂的高手,大部分都在挑戰自己能力邊界。最后祝大家都從文中有所收獲,成為sql高手!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的sql server numeric 可存几位小数_想成为优秀SQL高手?你就差这些细节的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对pca降维后的手写体数字图片数据分类_
- 下一篇: 随便下载!曝iPhone 16 Pro内