柚子快報邀請碼778899分享:最近一些SQL開發(fā)中碰到的問題
點擊標(biāo)題下「藍(lán)色微信名」可快速關(guān)注
最近做了一些數(shù)據(jù)庫應(yīng)用的開發(fā)工作,其實就是寫SQL進(jìn)行數(shù)據(jù)的整合,碰到一些小問題,有些問題還是比較典型的,或者說日常都可能碰到的,記錄一下,如有需要,可以參考。
問題1 數(shù)據(jù)整合的需求
MySQL數(shù)據(jù)庫,test表有如下記錄,需要根據(jù)a列相同值將b列字段用","進(jìn)行整合,例如此處應(yīng)該得到的是('a', 'a,b,c')和('b', 'a,b'),
可以用group_concat()函數(shù),實現(xiàn)此需求,
select a, group_concat(b separator ',') as data from test group by a;
返回如下,
group_concat()的使用可以參考官方文檔,
https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
問題2?MySQL的group_concat報錯"was cut by GROUP_CONCAT()"
如上個問題,用group_concat()函數(shù)時,可能會拋出異常,"SQL 錯誤 [1260] [HY000]: Row XXXX was cut by GROUP_CONCAT()"。
它的原因是group_concat()有個最大長度的限制,超過最大程度,就會提示這個,受參數(shù)group_concat_max_len的控制,可以查看global和session級別該參數(shù)當(dāng)前的值,默認(rèn)是1024,
select @@global.group_concat_max_len;
select @@session.group_concat_max_len;
因此,需要適當(dāng)調(diào)整這個參數(shù),才可以正常執(zhí)行g(shù)roup_concat(),
SET session group_concat_max_len=102400;
問題3 MySQL的case when
很多數(shù)據(jù)庫都提供了case when這種條件判斷的語法,MySQL中可以用case when對單個字段或多個字段進(jìn)行條件判斷并返回相應(yīng)的值,如下是單個字段進(jìn)行判斷的例子,如果name有值,則用then后的替換,如果name不是A、B、C,但是不為空,則用'it is others'替換,如果name是空,則顯示空,
select
??case?when?name?=?'A'?then?'it?is?A'
???????when name = 'B' then 'it is B'
???????when name = 'C' then 'it is C'
???????when name is not null then 'it is others'
???????else '' end as name
from test;
如下是多個字段進(jìn)行判斷的例子,會根據(jù)subject和score聯(lián)合進(jìn)行判斷,
SELECT
name,
subject,
score,
CASE
WHEN subject = 'Math' THEN
CASE
WHEN score >= 90 THEN 'Excellent'
WHEN score >= 80 THEN 'Very Good'
WHEN score >= 70 THEN 'Good'
ELSE 'Fair'
END
WHEN subject = 'English' THEN
CASE
WHEN score >= 90 THEN 'A*'
WHEN score >= 80 THEN 'A'
WHEN score >= 70 THEN 'B'
ELSE 'C'
END
ELSE 'N/A'
END AS grade_level
FROM
students;
問題4 MySQL數(shù)據(jù)庫中進(jìn)行字符串截取
像Java中可能經(jīng)常用到substring這種函數(shù)進(jìn)行字符串截取的操作,數(shù)據(jù)庫中同樣有這種函數(shù),MySQL中對應(yīng)的就是substring_index()。
如下表中數(shù)據(jù)需要根據(jù)兩個"/"之間的內(nèi)容進(jìn)行判斷返回不同的值,
substring_index()函數(shù)就派上用場,如下例子中substring_index()表示截取字符串a(chǎn)中第2個"/"之前的內(nèi)容,
select
case when substring_index(a, '/', 2) = '/Portugal' then 'POR'
when substring_index(a, '/', 2) = '/England' then 'GBR'
when substring_index(a, '/', 2) = '/France' then 'FRA'
???????else?'others'?end?as?name
from test;
得到如下值,
substring_index()函數(shù)可參考官方文檔,
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_substring-index
再多往前一步,上述例子中substring_index(a, '/', 2)返回的是帶"/"的字符串,例如"/Portugal",如果想得到"Portugal",可以用replace函數(shù)進(jìn)行替換,如下所示,
select replace(substring_index('/Portugal/Cristiano Ronaldo', '/', 2), '/', '') as name
就會返回這個,
其實很好理解,第二個參數(shù)是"/",第三個參數(shù)是''空,表示將字符串中所有的"/"用''空替代,具體還可參考官方文檔,
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_replace
問題5?SQL Server中截取URL
SQL Server中表數(shù)據(jù)如下,
現(xiàn)需要將"協(xié)議+域名或IP地址+端口"和其它內(nèi)容拆開,例如上述表中的第一條記錄拆成"http://localhost:13000"和"/test/a"兩個字段。
這個鏈接中有且僅有1個"http://",可能存在多個"/",從邏輯上來說,需要以第一個"/"為標(biāo)記,截取之前和之后的字符串。
此時可以用charindex進(jìn)行"/"的定位,
CHARINDEX ( expressionToFind , expressionToSearch [ , start_location ] )
expressionToFind :目標(biāo)字符串,就是想要找到的字符串,最大長度為8000?。
expressionToSearch :用于被查找的字符串。
start_location:開始查找的位置,為空時默認(rèn)從第一位開始查找。
"charindex('//', a)"可以找到"http://"的位置。
"charindex('//', a) + 2"表示跨過"http://"兩個字符的起始。
"charindex('/', a, charindex('//', a) + 2)"表示從"http://"后開始找到第一個"/"的位置,即"http://localost:13000/"。
可以用left函數(shù),得到某個位置左側(cè)的字符串,例如"left(a, charindex('/', a, charindex('//', a) + 2) - 1)",得到"http://localost:13000"。
可以用right函數(shù),得到某個位置右側(cè)的字符串,但需要計算截取的字符串長度,用a字段總長度和需要截取位置進(jìn)行相減操作,例如"right(a, len(a) - charindex('/', a, charindex('//', a) + 2) + 1)",得到"/test/a"。
完整SQL,如下所示,
select
a,
left(a, charindex('/', a, charindex('//', a) + 2) - 1) as address,
right(a, len(a) - charindex('/', a, charindex('//', a) + 2) + 1) as url
from test;
可以返回拆成兩個部分的內(nèi)容,
以上這些問題,雖然針對特定數(shù)據(jù)庫實現(xiàn)的,但是邏輯上,應(yīng)該都是通用的,只是不同數(shù)據(jù)庫,語法、函數(shù)存在差異,因此,還是可以借鑒的。寫SQL有時候和寫Java這些程序很像,雖然沒Java中的一些框架類,但從功能實現(xiàn)上,還是有很多等價的函數(shù)可用,想清楚邏輯,設(shè)計好處理步驟,能夠殊途同歸。
如果您認(rèn)為這篇文章有些幫助,還請不吝點下文章末尾的"點贊"和"在看",或者直接轉(zhuǎn)發(fā)朋友圈,
近期更新的文章:
《IT運維服務(wù)規(guī)范模板的參考》
《巡檢關(guān)注的通用指標(biāo)項》
《電話號的標(biāo)準(zhǔn)》
《揭開一些巴黎奧運會開幕式的細(xì)節(jié)》
《數(shù)據(jù)庫大咖的一場盛會(含贈票)》
熱文鑒賞:
《中國隊“自己的”世界杯》
《你不知道的C羅-Siu慶祝動作》
《架構(gòu)設(shè)計的15個關(guān)鍵概念》
《大阪環(huán)球影城避坑指南和功略》
《推薦一篇Oracle RAC Cache Fusion的經(jīng)典論文》
《"紅警"游戲開源代碼帶給我們的震撼》
文章分類和索引:
《公眾號1500篇文章分類和索引》
柚子快報邀請碼778899分享:最近一些SQL開發(fā)中碰到的問題
精彩內(nèi)容
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。