SQLSERVER根據特定字符截取字符串


寫SQL時經常會遇到需要根據特定字符去截取原始字符串的情況,簡單總結一下。

首先,准備工作:

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[MY_TEST](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FIELDSVALUE] [nvarchar](255) NULL,
CONSTRAINT [PK_MY_TEST] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];

INSERT INTO [dbo].[MY_TEST]
([FIELDSVALUE])
VALUES
('5yt5g/h.7yj/5e//435tsd'),
('//.we4rf6@gf/76iyg5t/ihjk//6yjf'),
('435t/56yg/53ytdh/56uyj/6ury/5utyjf/6uyrh/65uyhf/74urh/q4rtegsd//'),
('34tg3yuh/564yg'),
('65uej/78irj/658jg44g/6jy/'),
('34t/5euyhd/45yh/5yrth/5tr'),
('192.168.1.1');

執行查詢,

 

 自此,准備工作完成。

 

首先,我想看一下ID為3的那一行,‘/’總共出現了幾次:

SELECT len([FIELDSVALUE])-len(replace([FIELDSVALUE], '/', '')) AS [COUNTS] FROM [dbo].[MY_TEST] WHERE [ID] = 3;

 

 接着,我想看看 '/' 在ID=1時,首次出現的位置:

SELECT CHARINDEX('/',[FIELDSVALUE]) AS [INDEXOF] FROM [dbo].[MY_TEST] WHERE [ID] =1;

 

 然后,第二次出現的位置:

SELECT CHARINDEX('/',[FIELDSVALUE],CHARINDEX('/',[FIELDSVALUE])+1) AS [INDEXOF] FROM [dbo].[MY_TEST] WHERE [ID] = 1;

 

 

那么,想知道ID=1時,第一個'/'和第二個'/'之間的字串就很簡單了:

SELECT SUBSTRING([FIELDSVALUE],CHARINDEX('/',[FIELDSVALUE])+1,
CHARINDEX('/',[FIELDSVALUE],CHARINDEX('/',[FIELDSVALUE])+1)-CHARINDEX('/',[FIELDSVALUE])-1)
AS [NEWSTRING]
FROM [dbo].[MY_TEST]
WHERE [ID] = 1;

 

 

如果指定的分隔符確定不超過3個的話,還有個簡單的函數 PARSENAME ,該函數是用於域名解析的,先看下效果:

SELECT [ID], [FIELDSVALUE],
PARSENAME(REPLACE([FIELDSVALUE],'/','.'),4) AS [第四段],
PARSENAME(REPLACE([FIELDSVALUE],'/','.'),3) AS [第三段],
PARSENAME(REPLACE([FIELDSVALUE],'/','.'),2) AS [第二段],
PARSENAME(REPLACE([FIELDSVALUE],'/','.'),1) AS [第一段]
FROM [dbo].[MY_TEST]
WHERE [ID] = 7;

 

 可以看出,PARSENAME 函數解析域名時,是從后向前解析的,微軟官方提供的解釋為:PARSENAME ( 'object_name' , object_piece )

object_name '
是要為其檢索指定對象部分的對象的名稱。

object_piece
是要返回的對象部分。object_piece的類型為int,值可以為1,2,3,4

 

 

但是,有時候也會碰到這樣的情況:截取指定字符第N次出現和第N+1次出現時的字串。這個時候,單純的寫查詢SQL就會很繁瑣,就可以使用存儲過程去實現,

比如,我想知道 [ID] = 3 時,'/' 字符第6次和第7次出現時的中間字串。

先創建個存儲過程:

IF EXISTS(SELECT 1 FROM SYSOBJECTS WHERE NAME='SELECTINDEX')
DROP FUNCTION SELECTINDEX
GO
CREATE FUNCTION SELECTINDEX(@STRINGS NVARCHAR(200),@STRING NVARCHAR(10),@INDEX INT)
--@STRINGS:待查找字符串,@INDEX:位置
RETURNS INT
AS
BEGIN
DECLARE
@I INT,--當前找到第@I個
@POSITION INT--所在位置
SET @POSITION=1;
SET @I=0;
WHILE CHARINDEX(@STRING,@STRINGS,@POSITION)>0
BEGIN
SET @POSITION=CHARINDEX(@STRING,@STRINGS,@POSITION)+1;
SET @I=@I+1;
IF @I=@INDEX
BEGIN
RETURN @POSITION-1;
END
END
RETURN 0;--0表示未找到
END
GO

然后就簡單了:

SELECT SUBSTRING([FIELDSVALUE],
[dbo].SELECTINDEX([FIELDSVALUE],'/',6)+1,
[dbo].SELECTINDEX([FIELDSVALUE],'/',7)-([dbo].SELECTINDEX([FIELDSVALUE],'/',6)+1))
AS [NEWSTRING]
FROM [dbo].[MY_TEST]
WHERE [ID] = 3

 

 暫時先總結這么多,以后再補充。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM