SQL基礎操作_5_字串處理
7.6.1 生成自增值
需求:通過SQL生成一個1到1000條記錄.
解決方法:通過CTE的遞迴來實現該需求.
SQLServer:
DECLARE @startINT, @endINT SELECT @start=1, @end=1000 ;WITH NumberSequence( Number) AS ( SELECT @start ASNumber UNION ALL SELECT Number + 1 FROM NumberSequence WHERE Number <@end ) SELECT * FROM NumberSequence OPTION (MaxRecursion 1000)
執行結果:
Number |
1 |
2 |
3 |
... |
Oracle:
WITH t(num) AS (
SELECT 1 FROM DUAL
UNION ALL
SELECT t.num+1
FROM t WHERE t.num<100
)
SELECT * FROM t;
執行結果:
Num |
1 |
2 |
3 |
... |
Mysql(8.0及以上版本):
WITH RECURSIVE cte (num) AS
(
SELECT 1
UNION ALL
SELECT num+1 FROM cte WHERE num <100
)
SELECT * FROM cte;
執行結果:
Num |
1 |
2 |
3 |
… |
7.6.2 遍歷字串裡的每個值
需求:打印出ename為’King’的名字裡每一個字母,每個字母佔一行.
解決方法:通過自增表和emp表先cross join(笛卡爾積),然後再通過ename的len(ename的長度)進行過濾,最終得到顯示每個字母的結果.
SQLServer:
SELECT SUBSTRING (e.ENAME,seq.pos,1) AS ename_Split FROM (SELECT ENAME FROM emp WHERE ename= 'KING' ) e, (SELECT number AS pos FROM master.[dbo].[spt_values] WHERE type = 'P' AND number>0)seq WHERE seq.pos <= LEN(e.ename)
執行結果:
ename_Split |
K |
I |
N |
G |
注:
1: 這裡master.[dbo].[spt_values]是一張特殊的系統檢視,裡面存了從0到2047總2048條自增序列.
2: 如果不明白,可以分段來看.
Step1:
SELECT e.*,seq.* FROM
(SELECT ENAME FROM emp WHERE ename= 'KING' ) e,
(SELECT number AS pos FROM master.[dbo].[spt_values] WHERE type = 'P' AND number>0)seq
執行結果:
ENAME | pos |
KING | 1 |
KING | 2 |
KING | 3 |
… | … |
Sept2:
SELECT SUBSTRING(e.ENAME,seq.pos,1)AS ename_Split
FROM .. e, ..seq
WHERE seq.pos<=LEN(e.ename)
這裡通過SUBSTRNG函式,每次的開始位置不斷調整,每次僅取一個字元,再通過LEN函式過濾.所以得到最終結果.如果不熟悉SUBSTRING的語法,這裡簡單介紹下.
SUBSTRING ( expression, start, length )
1) 引數expression是要擷取的原始字串,比如這裡的” KING”
2) 引數start是要擷取的位置,比如從第2個位置開始,那應該從” I”往後數.
3) 引數length是要擷取的長度,沿用上一行的例子,如果長度定義為2,則最終擷取字串是”IN”
Oracle:
WITH t(num) AS (
SELECT 1 FROM DUAL
UNION ALL
SELECT t.num+1
FROM t WHEREt.num<100
)
SELECT SUBSTR(e.ENAME,seq.num,1) AS ename_Split FROM
(SELECT ENAME FROM emp WHERE ename ='KING' ) e,
(SELECT num FROM t)seq
WHERE seq.num <= LENGTH(e.ename)
Mysql 8.0:
WITH RECURSIVE cte (num)AS
(
SELECT 1
UNION ALL
SELECT num+1 FROM cte WHERE num <100
)
SELECT SUBSTRING(e.ENAME,seq.num,1) AS ename_Split FROM
(SELECT ENAME FROM emp WHERE ename ='KING' ) e,
(SELECT num FROM cte)seq
WHERE seq.num <= LENGTH(e.ename)
7.6.3 處理含引號的字串
需求:往dept表裡插入dname為Test’s,loc為Beijing,deptno為100的資料.
解決方法:這裡有位引號是特殊符號,所以需要特殊處理,比如如果雙引號包裹起來.
Mysql:
INSERT INTO dept VALUES(100,'Test\'s','Beijing');
Sql Server:
BEGIN TRAN
SET IDENTITY_INSERTdeptON;
GO
INSERT INTO dept(deptno,dname,loc) VALUES (100,'Test''s','Beijing');
SELECT * FROM dept WHERE deptno=100;
SET IDENTITY_INSERTdeptOFF;
GO
ROLLBACK TRAN
執行結果:
deptno | dname | loc |
100 | Test's | Beijing |
7.6.4 計算某個字元出現的次數
需求:查詢emp表emptno是7499的使用者的job裡S出現的次數.
解決方法:這裡length(len)結合replace函式算出字串出現的次數.
Sql Server:
SELECT empno,job,(LEN(JOB) - LEN(REPLACE(JOB,'S','')))/LEN('S') AS StrFreq
FROM emp WHERE empno=7499;
empno | job | StrFreq |
7499 | SALESMAN | 2 |
Mysql:
SELECT empno,job,ROUND((LENGTH(JOB) - LENGTH(REPLACE(JOB,'S','')))/LENGTH('S')) AS StrFreq
FROM emp WHERE empno=7499;
注:這裡除以LENGTH('S')是為了考慮傳入的字串是2位以及以上的情況,比如’SS’.
7.6.5 字串裡過濾不需要的字元
需求:過濾tmp_v視圖裡含數字的部分. 其中tmp_v檢視的data欄位的定義是emp表的ename欄位拼接空格和deptno欄位。
解決方法:這裡通過translate函式對含數字的部分進行替換.
SQL Server:
create view tmp_v
AS SELECT ename+' '+cast(deptno as varchar)as data
from emp
SELECT data,replace(dbo.translate(data,'0123456789','@@@@@@@@@@'),'@','') as ename FROM tmp_v
order by replace(dbo.translate(data,'0123456789','@@@@@@@@@@'),'@','') desc
data | ename |
WARD 30 | WARD |
TURNER 30 | TURNER |
SMITH 20 | SMITH |
SCOTT 20 | SCOTT |
MILLER 10 | MILLER |
MARTIN 30 | MARTIN |
KING 10 | KING |
JONES 20 | JONES |
JAMES 30 | JAMES |
FORD 20 | FORD |
CLARK 10 | CLARK |
BLAKE 30 | BLAKE |
ALLEN 30 | ALLEN |
ADAMS 20 | ADAMS |
注:這裡需要參考之前章節裡translate函式的實現.
Mysql:
create view tmp_v
AS SELECT CONCAT(ename,' ',deptno) as data
from emp
SELECT data,replace(translate(data,'0123456789','@@@@@@@@@@'),'@','') as ename
FROM tmp_v
order by replace(translate(data,'0123456789','@@@@@@@@@@'),'@','') desc
Oracle:
7.6.6 拆分字串裡的字元和數字
需求:過濾tmp_v視圖裡data欄位拆分會原來的ename和deptno兩個欄位.
解決方法:這裡通過translate、replace、repeate(replicate、rpad)函式對含數字的部分進行替換.
SQL Server:
SELECT data,replace(dbo.translate(data,'0123456789',REPLICATE('@',10)),'@','') as ename,
replace(dbo.translate(data,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',REPLICATE('@',26)),'@','') as deptno
FROM tmp_v
order by replace(dbo.translate(data,'0123456789',REPLICATE('@',10)),'@','') desc
data | ename | deptno |
WARD 30 | WARD | 30 |
TURNER 30 | TURNER | 30 |
SMITH 20 | SMITH | 20 |
SCOTT 20 | SCOTT | 20 |
MILLER 10 | MILLER | 10 |
MARTIN 30 | MARTIN | 30 |
KING 10 | KING | 10 |
JONES 20 | JONES | 20 |
JAMES 30 | JAMES | 30 |
FORD 20 | FORD | 20 |
CLARK 10 | CLARK | 10 |
BLAKE 30 | BLAKE | 30 |
ALLEN 30 | ALLEN | 30 |
ADAMS 20 | ADAMS | 20 |
Mysql:
SELECT data,replace(translate(data,'0123456789',REPEAT('@',10)),'@','') as ename,
replace(translate(data,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',REPEAT('@',26)),'@','') as deptno
FROM tmp_v
order by replace(translate(data,'0123456789',REPEAT('@',10)),'@','') desc
結果同上
Oracle:
7.6.7 判斷字串是字串數字型
需求:檢索temp_strdata表的欄位data是字串數字型別的記錄這裡如果都是字串或者數字的也符合條件.
解決方法:這裡通過translate、replace、repeate(replicate、rpad)函式對含數字的部分進行替換.
SqlServer:
CREATE TABLE temp_str(data VARCHAR(1000));
INSERT INTO temp_str VALUES('SMITH20');
INSERT INTO temp_str VALUES('JONES30');
INSERT INTO temp_str VALUES('Jim#40');
INSERT INTO temp_str VALUES('50$Tom');
INSERT INTO temp_str VALUES('60:Mike');
INSERT INTO temp_str VALUES('70Cruz');
INSERT INTO temp_str VALUES('Jack');
INSERT INTO temp_str VALUES('J8oh0n');
SELECT data --,dbo.translate(UPPER(data),'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',REPLICATE('a',36)) as trans
FROM temp_str
WHERE dbo.translate(UPPER(data),'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',REPLICATE('a',36))=REPLICATE('a',LEN(data))
或者用如下方法,思路通過判斷擷取的每個字元的ASCII值來判斷區間是否落在[48,57],[97,122],落在的為0,反之為1,然後再通過對該Flag進行sum來判斷,如果等於0則說明數字字元型的.
SELECT data -- ,SUM(Flag)
FROM
(
SELECT LOWER(data) as data,SUBSTRING(e.data,seq.pos,1)AS ename_Split,ascii(SUBSTRING(LOWER(e.data),seq.pos,1)) AS asci,
CASE WHEN ascii(SUBSTRING(LOWER(e.data),seq.pos,1))>= 48 AND ascii(SUBSTRING(LOWER(e.data),seq.pos,1))<=57 THEN 0
WHEN ascii(SUBSTRING(LOWER(e.data),seq.pos,1))>= 97 AND ascii(SUBSTRING(LOWER(e.data),seq.pos,1))<=122 THEN 0 ELSE 1 END AS Flag
FROM temp_str e,
(SELECT number AS pos FROM master.[dbo].[spt_values]WHERE type = 'P' AND number>0) seq
WHERE seq.pos<= LEN(e.data)
-- ORDER BY data
)A
GROUP BY data
HAVING SUM(Flag) = 0
Mysql:
SELECT data--,translate(UPPER(data),'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',REPEAT('a',36)) AS trans
FROM temp_str
WHERE translate(UPPER(data),'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',REPEAT('a',36))=REPEAT('a',LENGTH(data))
-- 利用正則表示式來匹配
SELECT data
FROM temp_str
WHERE data regexp'[^0-9A-Za-z]'=0
-- 待驗證Mysql8
WITH RECURSIVE cte (num) AS
(
SELECT 1
UNION ALL
SELECT num+1 FROM cte WHERE num <100
)
SELECT data-- ,SUM(Flag)
FROM
(
SELECT LOWER(data)as data,SUBSTRING(e.data,seq.pos,1) AS ename_Split,ascii(SUBSTRING(LOWER(e.data),seq.pos,1)) AS asci,
CASE WHEN ascii(SUBSTRING(LOWER(e.data),seq.pos,1))>=48 AND ascii(SUBSTRING(LOWER(e.data),seq.pos,1))<=57 THEN 0
WHEN ascii(SUBSTRING(LOWER(e.data),seq.pos,1))>=97 AND ascii(SUBSTRING(LOWER(e.data),seq.pos,1))<=122 THEN 0 ELSE 1 END AS Flag
FROM temp_str e,
(SELECT num FROM cte) seq
WHERE seq.pos<=LEN(e.data)
-- ORDER BY data
)A
GROUP BY data
HAVING SUM(Flag)=0
Oracle:
7.6.8 判斷字串含有漢字
需求:檢索含有漢字的字串.
解決方法:這裡通過函式CHAR_LENGTH對比LENGTH進行對比來判斷.
Mysql:
SELECT data,LENGTH(data) AS Len_data,CHAR_LENGTH(data) AS CharLen_Data,HEX(data) AS HexData FROM
(
SELECT 'Hello,World,SQL'AS data
UNION ALL
SELECT 'Data,Arithmetic' AS data
UNION ALL
SELECT 'Science中國' AS data
UNION ALL
SELECT '上S海H' AS data
)A
WHERE LENGTH(data) <> CHAR_LENGTH(data)
執行結果:
data | Len_data | CharLen_Data |
Science中國 | 13 | 9 |
上S海H | 8 | 4 |
注:
LENGTH() returnsthe length of the string measured in bytes.
CHAR_LENGTH() returns the length of the string measured incharacters.
LENGTH:是計算位元組的長度.一個漢字是算三個字元,一個數字或字母算一個字元
CHAR_LENGTH:漢字、數字、字母都算是一個字元
或者通過字串的十六進位制並結合REGEXP來判斷.
SELECT data,HEX(data) AS HexData FROM
(
SELECT 'Hello,World,SQL' AS data
UNION ALL
SELECT 'Data,Arithmetic'AS data
UNION ALL
SELECT 'Science中國' AS data
UNION ALL
SELECT '上S海H' AS data
)A
WHERE HEX(data) REGEXP'^(..)*(E[4-9])'
執行結果:
data | HexData |
Science中國 | 536369656E6365E4B8ADE59BBD |
上S海H | E4B88A53E6B5B748 |
SQL Server:
SELECT data FROM
(
SELECT 'Hello,World,SQL' AS data
UNION ALL
SELECT 'Data,Arithmetic' AS data
UNION ALL
SELECT 'Science中國' AS data
UNION ALL
SELECT '上S海H' AS data
)A
WHERE data LIKE '%[吖-座]%'
-- 或者利用PATINDEX函式進行判斷
SELECT data FROM
( SELECT 'Hello,World,SQL' AS data
UNION ALL
SELECT 'Data,Arithmetic' AS data
UNION ALL
SELECT 'Science中國' AS data
UNION ALL
SELECT '上S海H' AS data
)A
WHERE PATINDEX ('%[吖-座]%',data) > 0
執行結果:
data |
Science中國 |
上S海H |
Oracle:
7.6.9 合併多行到一行
需求:將emp表裡deptno相同的ename以逗號拼接在一起.
解決方法:這裡通過字串合併函式完成該效果.如group_concat
SQL Server:
SELECT DISTINCT
deptno
, STUFF((
SELECT N', '+ CAST([ename]ASVARCHAR(255))
FROM emp e1
WHERE e1.deptno= e2.deptno
FOR XML PATH ('')), 1, 2,'')AS StrCombine
FROM emp e2
執行結果:
Deptno | StrCombine |
10 | CLARK, KING, MILLER |
20 | SMITH, JONES, SCOTT, ADAMS, FORD |
30 | ALLEN, WARD, MARTIN, BLAKE, TURNER, JAMES |
或者藉助CTE:
WITH x(deptno,cnt,list,empno,len)
AS(
SELECT deptno,COUNT(*) OVER(PARTITIONBY deptno),CAST(ename AS VARCHAR(100)),empno,1
FROM emp
UNION ALL
SELECT x.deptno,x.cnt,CAST(x.list+','+e.ename AS VARCHAR(100)),e.empno,x.len+1
FROM emp e,x
WHERE e.deptno= x.deptno
AND e.empno> x.empno
)
SELECT deptno,list AS StrCombine from X
WHERE len=cnt
ORDER BY 1
步驟分析:
Step1: 首先借助COUNT(*) OVER(PARTITION BY deptno)確定每個部門裡有多少員工
Step2: 藉助len,初始值為1,完成自增(遞迴裡 x.len+1)
Step3: 藉助x.list+','+e.ename完成ename的拼接
Step4: 藉助e.deptno = x.deptno AND e.empno >x.empno確定要遞迴的結果集
Step5: 查詢滿足條件的記錄,即按deptno分組的empno數和自增序號相同的記錄.
分步檢視結果:
1) 檢視構建的遞迴資料.這裡以depto=10的為例:
SELECT * FROM x WHERE deptno= 10
deptno | cnt | list | empno | len |
10 | 3 | CLARK | 7782 | 1 |
10 | 3 | KING | 7839 | 1 |
10 | 3 | MILLER | 7934 | 1 |
10 | 3 | KING,MILLER | 7934 | 2 |
10 | 3 | CLARK,KING | 7839 | 2 |
10 | 3 | CLARK,MILLER | 7934 | 2 |
10 | 3 | CLARK,KING,MILLER | 7934 | 3 |
2) 不難發現,這裡高亮處的資料是我們想要的,所以通過如下方式獲取最終結果:
SELECT deptno,list AS StrCombine FROM X
WHERE len=cnt
ORDER BY 1
延展閱讀:如果僅想獲得某一個分組下的字串合併,也可以按照如下方法:
DECLARE @combinedString VARCHAR(MAX)
SELECT @combinedString = COALESCE(@combinedString+', ','')+ ename
FROM emp
WHERE deptno=10
SELECT @combinedString as StringValue
Mysql:
SELECT deptno,group_concat(ename) AS StrCombine FROM emp
GROUP BY deptno
ORDER BY emp.deptno,ename
7.6.10 對字串重新按字母排序重新組合
需求:將emp表裡ename按照字母順序重新組合生成新的字元.
解決方法:這裡通過字串合併函式或者結合substring和row_number完成該效果.
SqlServer:
WITH x(ename,ename_Split) AS
(
SELECT TOP 100000 ename,SUBSTRING(e.ENAME,seq.pos,1) AS ename_Split
FROM (SELECT ENAME FROM emp) e,
(SELECT number AS pos FROM master.[dbo].[spt_values] WHERE type= 'P' AND number>0) seq
WHERE seq.pos <= LEN(e.ename)
ORDER BY ename, ename_Split
)
SELECT DISTINCT
ename
, STUFF((
SELECT N''+ CAST(ename_SplitASVARCHAR(255))
FROM x e1
WHERE e1.ename= e2.ename
FOR XML PATH ('')),1,0,'')AS StrByAlph
FROM x e2
注: 如果想在CTE裡使用[]排序,需要在查詢裡指定TOP.
訊息 1033,級別 15,狀態 1,第 67 行
除非另外還指定了 TOP、OFFSET 或 FORXML,否則,ORDER BY 子句在檢視、行內函數、派生表、子查詢和公用表表達式中無效。
執行結果:
ename | StrByAlph |
ADAMS | AADMS |
ALLEN | AELLN |
BLAKE | ABEKL |
CLARK | ACKLR |
FORD | DFOR |
JAMES | AEJMS |
JONES | EJNOS |
KING | GIKN |
MARTIN | AIMNRT |
MILLER | EILLMR |
SCOTT | COSTT |
SMITH | HIMST |
TURNER | ENRRTU |
WARD | ADRW |
Mysql:
SELECT ename,group_concat(SUBSTRING(e.ENAME,seq.num,1) ORDER BY SUBSTRING(e.ENAME,seq.num,1) separator '') AS StrByAlph
FROM (SELECT ENAME FROM emp) e,
(SELECT i AS num FROM tb_incr)seq
WHERE seq.num <= LENGTH(e.ename)
GROUP BY ename
ORDER BY ename,SUBSTRING(e.ENAME,seq.num,1)
注: 這裡藉助group_concat函式裡的ORDER BY關鍵字,對已經排序的字母進行合併.
這裡tb_incr是個自增表,存放從1開始步長為1的自增序列
Oracle:
7.6.11 判斷一個字元是否是數字
需求:將臨時表裡判斷data欄位裡哪些是數字.
解決方法:這裡通過函式isnumberic或者regexp完成該效果.
Mysql:
DELIMITER $$
DROP FUNCTION IF EXISTS `IsNum` $$
CREATE FUNCTION `IsNum`(str VARCHAR(25)) RETURNS INT
BEGIN
DECLARE iResult INT DEFAULT 0;
IF ISNULL(str) THEN return 0;END IF;-- NULL 字串
IF str='' THEN return 0;END IF;-- 空字串
SELECT str REGEXP '^[0-9]*$' INTO iResult;
IF iResult =1 THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END $$
DELIMITER ;
或者使用正則表示式:
SELECT data FROM
(
SELECT '63' AS data
UNION ALL
SELECT '36(' AS data
UNION ALL
SELECT '3(6' AS data
UNION ALL
SELECT '(36' AS data
UNION ALL
SELECT '36$' AS data
UNION ALL
SELECT '' AS data
UNION ALL
SELECT NULL AS data
)A
-- WHERE IsNum(data) = 1
WHERE data REGEXP '^[0-9]*$'=1 AND data IS NOT NULL AND data<> '';
或者直接通過函式IsNum(data) = 1來判斷,見註釋部分.
SqlServer:
SELECT data FROM
(
SELECT '63' AS data
UNION ALL
SELECT '36(' AS data
UNION ALL
SELECT '3(6' AS data
UNION ALL
SELECT '(36' AS data
UNION ALL
SELECT '36$'AS data
UNION ALL
SELECT '' AS data
UNION ALL
SELECT NULL AS data
)A
WHERE ISNUMERIC(data)= 1
執行結果:
Data |
63 |
7.6.12 按照指定的位置擷取字元
需求:按照逗號拆分字串,取拆分出來的第二個子串.
解決方法:這裡需要自定義函式結合substring擷取字串,以達到該效果.
SQL Server:
CREATE FUNCTION strSplitIndex
( @str VARCHAR(1024), --要分割的字串
@split VARCHAR(10), --分隔符
@index INT --要取元素的位置
)
RETURNS VARCHAR(1024)
AS
BEGIN
DECLARE @location INT
DECLARE @start INT
DECLARE @next INT
DECLARE @seed INT
SET @str=LTRIM(RTRIM(@str))
SET @start=1
SET @next=1
SET @seed=LEN(@split)
SET @location=CHARINDEX(@split,@str)
WHILE @location<>0and @index>@next
BEGIN
SET @[email protected][email protected]
SET @location=CHARINDEX(@split,@str,@start)
SET @[email protected]+1
END
IF @location =0 SELECT @location =LEN(@str)+1
RETURN SUBSTRING(@str,@start,@[email protected])
END
GO
SELECT dbo.strSplitIndex(data,',',1) AS StrSplit FROM
(
SELECT 'Hello,World,SQL' AS data
UNION ALL
SELECT 'Data,Arithmetic' AS data
UNION ALL
SELECT 'Science' AS data
)A
執行結果:
StrSplit |
Hello |
Data |
Science |
或者藉助parsename函式:
SELECT PARSENAME(REPLACE(data,',','.'),2) AS StrSplit FROM
(
SELECT 'Hello,World,SQL' AS data
UNION ALL
SELECT 'Data,Arithmetic' AS data
UNION ALL
SELECT 'Science' AS data
)A
WHERE PARSENAME(REPLACE(data,',','.'),2)IS NOT NULL
執行結果:
StrSplit |
Hello |
Data |
Mysql:
SELECT data,SUBSTRING_INDEX(SUBSTRING_INDEX(data,',',seq.num),',',-1) AS sub,seq.num AS subStrPos
FROM
(SELECT 'Hello,World,SQL' AS data
UNION ALL
SELECT 'Data,Arithmetic' AS data
UNION ALL
SELECT 'Science' AS data) e,
(SELECT ias num FROM tb_incr)seq
WHERE seq.num <= LENGTH(e.data)- LENGTH(REPLACE(e.data,',',''))+1
AND seq.num=2
ORDER BY data,seq.num
執行結果:
data | sub | subStrPos |
Data,Arithmetic | Arithmetic | 2 |
Hello,World,SQL | World | 2 |
步驟解析:
Step1: 首先借助自增表將data欄位裡的資料按照逗號的數目切分,如果有2個逗號,則會切分成3部分
Step2: 藉助SUBSTRING_INDEX函式擷取逗號所在位置的子串,這裡鑑於SUBSTRING_INDEX的第三個引數的意義是子串累加,所以又套了個SUBSTRING_INDEX,第三個引數傳-1,即從右邊擷取.
Step3:藉助自增表的num,取指定分割位置的資料,這裡是2.
注: SUBSTRING_INDEX函式執行示例見下:
SELECT SUBSTRING_INDEX('Hello,World,SQL',',',1) AS SUBSTRING,1 AS pos
UNION ALL
SELECT SUBSTRING_INDEX('Hello,World,SQL',',',2) AS SUBSTRING,2 AS pos
UNION ALL
SELECT SUBSTRING_INDEX('Hello,World,SQL',',',3) AS SUBSTRING,3 AS pos
執行結果:
SUBSTRING | pos |
Hello | 1 |
Hello,World | 2 |
Hello,World,SQL | 3 |
Oracle:
7.6.13 按照指定的分隔符擷取字元返回表形式
需求:按照逗號拆分字串,並指定返回的格式是表.
解決方法:這裡需要自定義函式結合substring擷取字串,以達到該效果.
SQLServer:
CREATE FUNCTION strSplitTable(@strNVARCHAR(2000),@splitNVARCHAR(2))
RETURNS @t TABLE(SubStr VARCHAR(1000))
AS
BEGIN
DECLARE @tmpSubStr VARCHAR(1000),@getIndexINT
SET @getIndex=CHARINDEX(',',@str)
WHILE(@getIndex<>0)
BEGIN
SET @tmpSubStr=CONVERT(VARCHAR(1000),SUBSTRING(@str,1,@getIndex-1))
INSERT INTO @t(SubStr)VALUES(@tmpSubStr)
SET @str=STUFF(@str,1,@getIndex,'')
SET @getIndex=CHARINDEX(',',@str)
END
INSERT INTO @t(SubStr)VALUES(@str)
RETURN
END
GO
SELECT * FROM strSplitTable('Hello,World,SQL',',')
執行結果:
SubStr |
Hello |
World |
SQL |
注: 自Sql Server 2016已新增系統函式STRING_SPLIT,測試示例見下:
SELECT A.value value_A,B.value value_B
FROM
( SELECT value FROM STRING_SPLIT('A$B$C','$')
)A
LEFT JOIN
(SELECT value FROM STRING_SPLIT('A,B',',')
)B
ON A.value = B.value
執行結果:
value_A | value_B |
A | A |
B | B |
C | NULL |
這裡僅支援單個字元的分隔符.
訊息 214,級別 16,狀態 11,第 12 行
Procedure expects parameter 'separator' of type 'nchar(1)/nvarchar(1)'.
Mysql:
未見該方法.
相關推薦
SQL基礎操作_5_字串處理
7.6.1 生成自增值需求:通過SQL生成一個1到1000條記錄.解決方法:通過CTE的遞迴來實現該需求.SQLServer:DECLARE @startINT, @endINT SELECT @start=1, @end=1000 ;WITH NumberSequence(
SQL基礎操作
esc order by author con set 創建數據庫 之間 hits 開始 SQL是操作數據的語言 增加記錄: insert into 數據表名稱(字段1,字段2,字段3....)values(值1,值2,值3.....) 刪除記錄: delete from
SQL基礎操作匯總
join 賬號 oracl mail lec width enc 比較 upd SQL基礎操作匯總 一、表操作 1、表的創建(CREATE TABLE): 基本語句格式: CREATE TABLE table_name ( col_name dataty
Go基礎程式設計:字串處理
字串在開發中經常用到,包括使用者的輸入,資料庫讀取的資料等,我們經常需要對字串進行分割、連線、轉換等操作,我們可以通過Go標準庫中的strings和strconv兩個包中的函式進行相應的操作。 1 字串操作 下面這些函式來自於strings包,這裡介
SQL基礎操作_3_資料字典
7.5.1 列出模式中所有的表需求:查詢給定模式下建立的所有表和建立時間。解決方法:通過各個資料庫裡提供的系統檢視查詢。Sql Server:USE Shenl; GO SELECT TABLE_NAME FROM INFORMATION_SCHEMA.tables WHERE TABLE_TYPE='BAS
C# 資料操作系列 - 1. SQL基礎操作
# 0.前言 前篇介紹了一些資料庫的基本概念和以及一些常見的資料庫,讓我們對資料庫有了一個初步的認識。這一篇我們將繼續為C#資料操作的基礎填上一個空白-SQL語句。 SQL(Structured Query Language,結構化查詢語言)是一種特定的程式語言,用於管理資料庫系統,操作資料甚至編寫一些程
前端(十二)—— JavaScript基礎操作:if語句、for循環、while循環、for...in、for...of、異常處理、函數、事件、JS選擇器、JS操作頁面樣式
結束 建議 prop map、set -c 表單元素 tle form collect JavaScript基礎操作 一、分支結構 1、if語句 if 基礎語法 if (條件表達式) { 代碼塊; } // 當條件表達式結果為true,會執行代碼塊;反之不執行
使用Mysql執行SQL語句基礎操作
SQL: 又叫結構化語言,是一種用來操作RDBMS的資料庫語言,在關係型資料庫中都支援使用SQL語句,如oracle、mysql等等。 注意: 在關係型資料庫中sql語句是通用的,而在非關係型資料庫中是不支援sql語句的,每種非關係型資料庫都有自己的查詢語言,是不通用的。 注意: sq
sqlite的sql語句中使用字串操作
sqlite的字串操作有:substr,replace等等。 本文通過replace的使用例子演示一下大概怎麼使用。 官網上是這麼說的: replace(X,Y,Z) The replace(X,Y,Z) function returns a string formed by
C語言字串處理基礎函式(一)
1.strlen()函式 功能:函式返回字串str 的長度( 即空值結束符之前字元數目,不包括控制結束符)。 語法: #include <string.h> size_t strlen( char *str ); 例子: #include <stdio
linux資料夾遍歷字串處理等基礎功能函式
/************************************************************************* > File Name: filenameio.h > Author: lcmf > Mail: [e
c# 字串基礎操作
1 字串輸出 int a=0; int b=1; Console.WriteLine("b班和a班分別有{1},{0}人{{}}",a,b); Console.
sql語句字串處理函式
函式 database() 查詢當前所使用的資料庫名 user() 或 current_user() 查詢當前使用者 version() 或 @@version 檢視當前資料庫的版本 文字處理函式 eg: mysql> SELECT LEFT('
【python資料處理】pandas基礎操作
基礎操作 1.建立表 dataframe 類似於csv 與SQL表 方法1 import codecademylib import pandas as pd df1 = pd.DataFrame({ 'Product ID': [1, 2
python學習筆記之基礎操作(五)字串格式化(1)%格式化
格式化基本格式 s = "i am %s ,i am %d years old ,and i like %s"%("haiyang",20,"zhu") print(s) #區分資料型別,無法自動在字串
python學習筆記之基礎操作(五)字串格式化(2)format
format格式化 1,基本格式 #對於每一個大括號,在後面的引數中找到對應的引數插進來 #format操作類似於於將傳入的引數製成多個數據的資料結構元組或者字典,然後依照索引插入引數 s = "i a
go語言基礎語法:異常處理,文字檔案處理,JSON處理,檔案操作
一、異常處理 1.err介面的使用 err1 := fmt.Errorf("%s", "this is normal error") fmt.Println("err1=", err1) err2 := errors.New("this is normal error,
MySQL資料庫基礎操作:安裝+登入+SQL操作語句+資料庫授權、備份、恢復+其他操作
Mysql最流行的RDBMS(關係型資料庫系統),特別是在WEB應用方面:特點 資料以表格的形式出現 每行為各種記錄名稱 每列為記錄名稱所對應的資料域 許多的行和列組成一張表單 若干的表單組成的database RDBMS的一些術語 資料庫、資料表、列、行、外
Boost(五)——字串處理(一):字串操作
由於這一章內容過多,我將採用三個小章,精簡原文三個小部分內容。 區域設定: setlocale(LC_ALL,“”) locale::global(std::locale("German")); //設定全域性區域德語環境 字串操作: 一、將字串所有字元轉成大寫
Boost(五)——字串處理(二):正則表示式操作
正則表示式: 一些簡單的描述符: . 匹配除換行符以外的任意字元 \w 匹配字母或數字或下劃線或漢字 等價於 '[^A-Za-z0-9_]'。 \s 匹配任意的空白符 \d 匹配數字 \b 匹配單詞的開始或結束 ^ 匹配字串的開始 $ 匹配字串的結束 一、字