1. 程式人生 > >SQL基礎操作_5_字串處理

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 匹配單詞的開始或結束 ^ 匹配字串的開始 $ 匹配字串的結束 一、字