關於SQL的幾道小題詳解 sql高階

2022-09-29 05:18:10 字數 3385 閱讀 2054

當我們拿到題目的時候,並不是急於作答,那樣會得不償失的,而是分析思路,採用什麼方法,達到什麼目的,還要思考有沒有簡單的方法或者通用的方法等等,這樣才會達到以一當十的效果,這樣的慣性思維其實早在我們度高中的時候就被領教了,所謂「萬變不離其宗」吧。以下各題來自日常所見,或qq群,或面試題,或部落格園。

題目一:如下表所示,現需要按照收款員統計收款和退款合計金額。

實現結果需如下顯示:

分析:想要的結果(記為表b)和源資料(記為表a)相比,有共同的列(收款員),不同的是表a的金額根據標記和收款員分成了兩列,所以這個需求可以用語言表述一下:首先根據收款員分組(group by),然後當標記為「收」時,金額計入收款合計(sum);當標記為「退」時,金額計入退款合計(sum)。當……時……,這不就是sql的條件判斷嘛?盤點sql的條件語句不多,if……else……和case……when……then……else……end。這樣問題就迎刃而解了。

解決方案如下:

with ta as

(select '收' as 標記,'100' as 收款員,150 as 金額

union

select '收','100',375

union

select '退','100',78

union select '收','200',74

)select 收款員,sum(case when 標記='收' then 金額 else 0 end) as 收款合計,

sum(case when 標記='退' then 金額 else 0 end) as 退款合計 from ta

group by 收款員

題目二:如下表a(左邊)職員資訊表,其中id為職員工號,name為職員姓名;表b(右邊)為職員任務分配表,其中id為職員工號(和表a中id對應),task為任務編號。

現需求每個職員的任務數。結果如下顯示:

其實原題是這樣的:只有一張表b,求求每個職員的任務數。沒有找到比較好的方法實現,不做討論,歡迎高人指點。

分析:此題的難點在於表b中的id複雜表示,其實這樣有悖於資料庫的設計原則,理應表a和表b的id一一對應。既然是題,我們只能從當前的條件入手了,攻破難點的關鍵在於判斷a中id在b中id出現與否,如果出現那麼如何統計出現的次數。判斷出現與否需要用到函式charindex。

解決方案如下:

--建立測試資料

with ta

as(select '1,2' as id,'job1' as task

union select '1,2,3','job3'

union select '2,3','job2'

union select '3,4,5','job4')

,tb as

(select '1' as id,'張三' as name

union select '2','王二'

union select '3','李四'

union select '4','李明'

union select '5','王五')

select b.id,b.name,count(1) as www.cppcns.comtasks

from ta a,tb b

where charindex(b.id,a.id)>0

group by b.id,b.name

order by b.id

題目三:原題參見這篇文章:

如下表city所示,code為行政區域碼(六位數字,前兩代表省級,中間兩位代表市級,最後兩位代表縣級,不考慮xx00xx情況),city為城市名稱,ccode為該城市所屬的省級或者市級行政區域碼。

現需求如下結果:

分析:分析表city,code的含義十分明顯,所需要的結果也很明顯,如果是省就是顯示省份;是市則顯示為所屬省級+市級;是縣級則顯示為所屬省級+所屬市級+縣級。貌似可以用題目一分析中提到的sql條件語句實現,但是轉念一想,還是有差別,這裡需要先判斷city屬於省級?市級?縣級?然後在對應起來的,這樣還得有參照表,複雜了。回到結果表中來進行分析,其實判定city屬於省市縣的問題並不難,code的含義已經說明了,只要轉換表述:在表city中,當code的後四位為「0000」時,肯定是省級;當code的後兩位為「00」,並且後四位不為「0000」時,肯定是市級;當code後兩位不為「00」時,為縣級。這樣省市縣的判定就一目了然了,然後,根據市級編碼追朔所屬的省級,並得出所屬省級+市級,縣級追朔所屬的市級,得出所屬省級+所屬市級+所屬縣級,通過運用這種簡單的遞迴思想,解決方案程式設計客棧便躍然紙上了。

解決方案如下:

--測試資料

with ta as

(select '110000' as code, '北京市' city, '110000' ccode

union

select n'110200', n'西城區', n'110200'

union

select n'110300', n'崇文區', n'11程式設計客棧0300'

union

select n'430000', n'湖南省', n'430000'

union

select n'430100', n'長沙市', n'430100'

union

select n'430101', n'望城yeuyrj縣', n'430100')

select * into city from ta

select * from city;

--解決方案

with ta

as(--省級

select code,city,ccode,city content from city where right(code,4)='0000'),

tb as(

--市級

select b.code,b.city,b.ccode,a.city+','+b.city as content from ta a,city b where left(a.ccode,2)=left(b.ccode,2)

and right(b.code,2)='00' and right(b.code,4)<>'0000'),

tc as(

select c.code,c.city,c.ccode,b.content+','+c.city content from tb b,city c whyeuyrjere left(b.ccode,4)=left(c.ccode,4)

and right(c.code,2)<>'00')

select * from ta

union

select * from tb

union

select * from tc

通過上述幾道小題,常思常新,溫故了sql的部分知識,當然方法很多,變式很多,如題目二統計表b中每個task的人數等。不足之處,歡迎各位指點!

本文標題: 關於sql的幾道小題詳解(sql高階)

本文位址:

關於sql注入(詳解)

sql注入是比較常見的網路攻擊方式之一,它不是利用作業系統的bug來實現攻擊,而是針對程式設計師程式設計時的疏忽,通過sql語句,實現無帳號登入,甚至篡改資料庫。償試所有可以輸入的地方,償試注入攻擊。根據返回的報錯結果,判斷後台服務的型別及資料庫的型別。確認後台服務及資料庫型別後,改進攻擊方案,進行...

幾道比較難的SQL題

select from article where create timenow article time order by create time asc limit 1 select a.rownum rownum 1 as rowno from a,select rownum 3 b通過變數r...

你能答對幾道SQL題?

我們使用的是postgresql資料庫,以下是在審核和優化開發人員sql時發現的一些問題,現整理共享出來希望對各位有用,每個案例先都構造了一部分資料,然後提乙個問題,看是否你能回答出來 記住先不要看執行結果 然後把你的結果和實際結果對比看差異在 一切的答案在執行計畫中會告訴你。案例1 droptab...