SQL基礎操作之字符串處理操作教程

轉載自:https://www.2cto.com/database/201802/718583.html

7.6.1 生成自增值
需求:

通過SQL生成一個1到1000條記錄.

解決方法:

通過CTE的遞歸來實現該需求.

SQLServer:

?
1
2
3
4
5
6
7
8
9
10
11
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

4

5

6

7

8

9

10

…

Oracle:

?
1
2
3
4
5
6
7
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

4

5

6

7

8

9

10

…

Mysql(8.0及以上版本):

?
1
2
3
4
5
6
7
WITH RECURSIVE cte (num) AS
(
  SELECT 1
  UNION ALL
  SELECT num+1 FROM cte WHERE num <100
)
SELECT * FROM cte;
執行結果:

Num

1

2

3

4

5

6

7

8

9

10

…

7.6.2 遍歷字符串裏的每個值
需求:

打印出ename爲’King’的名字裏每一個字母,每個字母佔一行.

解決方法:

通過自增表和emp表先cross join(笛卡爾積),然後再通過ename的len(ename的長度)進行過濾,最終得到顯示每個字母的結果.

SQLServer:

?
1
2
3
4
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:

?
1
2
3
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

KING

4

KING

5

KING

6

KING

7

KING

8

…

…

Sept2:

?
1
2
3
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:

?
1
2
3
4
5
6
7
8
9
10
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)
Mysql8.0:

?
1
2
3
4
5
6
7
8
9
10
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:

?
1
INSERT INTO dept VALUES(100,'Test\'s','Beijing');
Sql Server:

?
1
2
3
4
5
6
7
8
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:

?
1
2
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:

?
1
2
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:

?
1
2
3
4
5
6
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:

?
1
2
3
4
5
6
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)函數對含數字的部分進行替換.

SQLServer:

?
1
2
3
4
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:

?
1
2
3
4
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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則說明數字字符型的.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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:

?
1
2
3
4
5
6
7
8
9
10
11
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來判斷.

?
1
2
3
4
5
6
7
8
9
10
11
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'ASdata

UNION ALL

SELECT 'Data,Arithmetic'ASdata

UNION ALL

SELECT 'Science中國'ASdata

UNION ALL

SELECT '上S海H'AS data

)A

WHERE data LIKE '%[吖-座]%'

或者利用PATINDEX函數進行判斷

SELECTdata FROM

(

SELECT 'Hello,World,SQL'ASdata

UNION ALL

SELECT 'Data,Arithmetic'ASdata

UNION ALL

SELECT 'Science中國'ASdata

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(enameASVARCHAR(100)),empno,1

FROM emp

UNION ALL

SELECT x.deptno,x.cnt,CAST(x.list+','+e.enameASVARCHAR(100)),e.empno,x.len+1

FROM emp e,x

WHERE e.deptno= x.deptno

AND e.empno> x.empno

)

SELECT deptno,listAS StrCombinefrom 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 xWHERE 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,listAS StrCombinefrom 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

GROUPBY deptno

ORDERBY 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 ENAMEFROM emp) e,

(SELECT numberAS posFROMmaster.[dbo].[spt_values]WHEREtype = '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)ORDERBYSUBSTRING(e.ENAME,seq.num,1)separator'')AS StrByAlph

FROM (SELECT ENAMEFROM emp) e,

(SELECT iAS numFROM tb_incr)seq

WHERE seq.num<=LENGTH(e.ename)

GROUPBY ename

ORDERBY ename,SUBSTRING(e.ENAME,seq.num,1)

注: 這裏藉助group_concat函數裏的ORDER BY關鍵字,對已經排序的字母進行合併.

Oracle:

7.6.11 判斷一個字符是否是數字
需求:

將臨時表裏判斷data字段裏哪些是數字.

解決方法:

這裏通過函數isnumberic或者regexp完成該效果.

Mysql:

DELIMITER $$

DROP FUNCTIONIFEXISTS `IsNum` $$

CREATE FUNCTION `IsNum`(strVARCHAR(25)) RETURNSINT

BEGIN

DECLARE iResultINTDEFAULT0;

IFISNULL(str)THENreturn0;END IF;-- NULL 字符串

IF str=''THENreturn0;END IF;-- 空字符串

SELECT strREGEXP'^[0-9]*$'INTO iResult;

IF iResult=1THEN

RETURN1;

ELSE

RETURN0;

END IF;

END $$

DELIMITER ;

或者使用正則表達式:

SELECT dataFROM

(

SELECT'63'AS data

UNIONALL

SELECT'36('AS data

UNIONALL

SELECT'3(6'AS data

UNIONALL

SELECT'(36'AS data

UNIONALL

SELECT'36$'AS data

UNIONALL

SELECT''AS data

UNIONALL

SELECTNULLAS data

)A

-- WHERE IsNum(data) = 1

WHERE data REGEXP'^[0-9]*$'=1AND data ISNOTNULLAND data<>'';

或者直接通過函數IsNum(data) = 1來判斷,見註釋部分.

SqlServer:

SELECT data FROM

(

SELECT '63'ASdata

UNION ALL

SELECT '36('ASdata

UNION ALL

SELECT '3(6'ASdata

UNION ALL

SELECT '(36'ASdata

UNION ALL

SELECT '36$'ASdata

UNION ALL

SELECT ''AS data

UNION ALL

SELECT NULLASdata

)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 @start=@location+@seed

SET @location=CHARINDEX(@split,@str,@start)

SET @next=@next+1

END

IF @location =0 SELECT @location =LEN(@str)+1

RETURN SUBSTRING(@str,@start,@location-@start)

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'ASdata

UNION ALL

SELECT 'Data,Arithmetic'AS data

UNION ALL

SELECT 'Science' AS data

)A

WHERE PARSENAME(REPLACE(data,',','.'),2)ISNOT 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

UNIONALL

SELECT'Data,Arithmetic'AS data

UNIONALL

SELECT'Science'AS data) e,

(SELECT ias numFROM tb_incr)seq

WHERE seq.num<=LENGTH(e.data)-LENGTH(REPLACE(e.data,',',''))+1

AND seq.num=2

ORDERBY 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函數執行示例見下:

SELECTSUBSTRING_INDEX('Hello,World,SQL',',',1)ASSUBSTRING,1AS pos

UNIONALL

SELECTSUBSTRING_INDEX('Hello,World,SQL',',',2)ASSUBSTRING,2AS pos

UNIONALL

SELECTSUBSTRING_INDEX('Hello,World,SQL',',',3)ASSUBSTRING,3AS 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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章