查找字符串中字符的最后一次出现
Find last occurence of a character within a string
如果这个字符串放在斜杠之间,如何从这个字符串中获取一个字符串,需要在这个函数中添加功能
SELECT FieldA, COALESCE(RIGHT(FieldA, NULLIF(CHARINDEX('/', REVERSE(FieldA)) - 1, -1)), FieldA, '') AS FieldB
FROM (
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA UNION ALL
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD' UNION ALL
SELECT NULL
) TableA
表示这个字符串'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/'
或
这个字符串'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
或
这个字符串'/index.cfm/fuseaction/content.page/nodeID/asdasd/'
UPD(抱歉): 并不总是这是 GUID,也不总是恰好是 content.page/nodeID
- 这总是介于或开始斜杠 [=15] 之间的某个字符串=]
献给那些喜欢 monster 1-liners 的人。
对于 MS2012 - 使用 IIF
:
SELECT IIF(CHARINDEX('/', REVERSE(FieldA)) = 1,REVERSE(SUBSTRING(REVERSE(FieldA),2,CHARINDEX('/', SUBSTRING(REVERSE(FieldA), 2, LEN(FieldA))) - 1)),REVERSE(SUBSTRING(REVERSE(FieldA),1,CHARINDEX('/', REVERSE(FieldA)) - 1)))
FROM (
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA
UNION ALL
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
UNION ALL
SELECT NULL
) TableA
对于 MS2008 下面是相同的代码 CASE
SELECT A.FieldA
, CASE
WHEN CHARINDEX('/', REVERSE(FieldA)) = 1 THEN REVERSE(SUBSTRING(REVERSE(FieldA),2,CHARINDEX('/', SUBSTRING(REVERSE(FieldA), 2, LEN(FieldA))) - 1))
ELSE REVERSE(SUBSTRING(REVERSE(FieldA),1,CHARINDEX('/', REVERSE(FieldA)) - 1))
END
FROM (
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA
UNION ALL
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
) a
这将在您的数据中找到任何 GUID,因为它使用递归检查两个正斜杠之间的每个字符串
SELECT * INTO TableA
FROM
(
SELECT 1 AS ID,'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA
UNION ALL
SELECT 2,'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
--UNION ALL
--SELECT NULL
) tableA;
--CleanTableA makes sure that all values in FieldA end with a forward slash
WITH CleanTableA
AS
(
SELECT ID,
CASE
WHEN RIGHT(FieldA,1) = '/' THEN FieldA
ELSE FieldA + '/'
END FieldA
FROM tableA
),
--Recursively finds the location of each forward slash
--RecursionCount tells me if its the first,second,third,etc... forward slash
yourRecursiveCTE
AS
(
SELECT ID,FieldA,CHARINDEX('/',FieldA,0) AS start, 1 AS recursionCount
FROM CleanTableA
UNION ALL
SELECT CleanTableA.ID,CleanTableA.FieldA,CHARINDEX('/',CleanTableA.FieldA,CHARINDEX('/',CleanTableA.FieldA,yourRecursiveCTE.start) + 1) start,recursionCount + 1
FROM CleanTableA
INNER JOIN yourRecursiveCTE
ON yourRecursiveCTE.ID = CleanTableA.ID
WHERE CHARINDEX('/',CleanTableA.FieldA,CHARINDEX('/',CleanTableA.FieldA, yourRecursiveCTE.start) + 1) <> 0
)
SELECT A.ID,
A.FieldA,
--Finds the gaps in between the "/"
SUBSTRING(A.fieldA,A.start + 1,B.start-A.start - 1) possible_guid,
--Tries to convert them to see if they are a GUID, if so then it returns the value
TRY_CONVERT(uniqueidentifier,SUBSTRING(A.fieldA,A.start + 1,B.start-A.start - 1)) actual_guid
FROM yourRecursiveCTE A
INNER JOIN yourRecursiveCTE B
--Only compare the same values with same ID
ON A.ID = B.ID
--Join to forwards slash before it
AND A.recursionCount = B.recursionCount -1
--Uncomment where clause to only display GUID's
--WHERE TRY_CONVERT(uniqueidentifier,SUBSTRING(A.fieldA,A.start + 1,B.start-A.start - 1)) IS NOT NULL
ORDER BY A.ID,B.recursionCount
--Cleanup
DROP TABLE TableA
结果:
ID FieldA possible_guid actual_guid
----------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------------------------------------
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ index.cfm NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ fuseaction NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ content.page NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ nodeID NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ index.cfm NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ fuseaction NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ content.page NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ nodeID NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD
如果这个字符串放在斜杠之间,如何从这个字符串中获取一个字符串,需要在这个函数中添加功能
SELECT FieldA, COALESCE(RIGHT(FieldA, NULLIF(CHARINDEX('/', REVERSE(FieldA)) - 1, -1)), FieldA, '') AS FieldB
FROM (
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA UNION ALL
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD' UNION ALL
SELECT NULL
) TableA
表示这个字符串'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/'
或
这个字符串'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
或
这个字符串'/index.cfm/fuseaction/content.page/nodeID/asdasd/'
UPD(抱歉): 并不总是这是 GUID,也不总是恰好是 content.page/nodeID
- 这总是介于或开始斜杠 [=15] 之间的某个字符串=]
献给那些喜欢 monster 1-liners 的人。
对于 MS2012 - 使用 IIF
:
SELECT IIF(CHARINDEX('/', REVERSE(FieldA)) = 1,REVERSE(SUBSTRING(REVERSE(FieldA),2,CHARINDEX('/', SUBSTRING(REVERSE(FieldA), 2, LEN(FieldA))) - 1)),REVERSE(SUBSTRING(REVERSE(FieldA),1,CHARINDEX('/', REVERSE(FieldA)) - 1)))
FROM (
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA
UNION ALL
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
UNION ALL
SELECT NULL
) TableA
对于 MS2008 下面是相同的代码 CASE
SELECT A.FieldA
, CASE
WHEN CHARINDEX('/', REVERSE(FieldA)) = 1 THEN REVERSE(SUBSTRING(REVERSE(FieldA),2,CHARINDEX('/', SUBSTRING(REVERSE(FieldA), 2, LEN(FieldA))) - 1))
ELSE REVERSE(SUBSTRING(REVERSE(FieldA),1,CHARINDEX('/', REVERSE(FieldA)) - 1))
END
FROM (
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA
UNION ALL
SELECT '/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
) a
这将在您的数据中找到任何 GUID,因为它使用递归检查两个正斜杠之间的每个字符串
SELECT * INTO TableA
FROM
(
SELECT 1 AS ID,'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/' AS FieldA
UNION ALL
SELECT 2,'/index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD'
--UNION ALL
--SELECT NULL
) tableA;
--CleanTableA makes sure that all values in FieldA end with a forward slash
WITH CleanTableA
AS
(
SELECT ID,
CASE
WHEN RIGHT(FieldA,1) = '/' THEN FieldA
ELSE FieldA + '/'
END FieldA
FROM tableA
),
--Recursively finds the location of each forward slash
--RecursionCount tells me if its the first,second,third,etc... forward slash
yourRecursiveCTE
AS
(
SELECT ID,FieldA,CHARINDEX('/',FieldA,0) AS start, 1 AS recursionCount
FROM CleanTableA
UNION ALL
SELECT CleanTableA.ID,CleanTableA.FieldA,CHARINDEX('/',CleanTableA.FieldA,CHARINDEX('/',CleanTableA.FieldA,yourRecursiveCTE.start) + 1) start,recursionCount + 1
FROM CleanTableA
INNER JOIN yourRecursiveCTE
ON yourRecursiveCTE.ID = CleanTableA.ID
WHERE CHARINDEX('/',CleanTableA.FieldA,CHARINDEX('/',CleanTableA.FieldA, yourRecursiveCTE.start) + 1) <> 0
)
SELECT A.ID,
A.FieldA,
--Finds the gaps in between the "/"
SUBSTRING(A.fieldA,A.start + 1,B.start-A.start - 1) possible_guid,
--Tries to convert them to see if they are a GUID, if so then it returns the value
TRY_CONVERT(uniqueidentifier,SUBSTRING(A.fieldA,A.start + 1,B.start-A.start - 1)) actual_guid
FROM yourRecursiveCTE A
INNER JOIN yourRecursiveCTE B
--Only compare the same values with same ID
ON A.ID = B.ID
--Join to forwards slash before it
AND A.recursionCount = B.recursionCount -1
--Uncomment where clause to only display GUID's
--WHERE TRY_CONVERT(uniqueidentifier,SUBSTRING(A.fieldA,A.start + 1,B.start-A.start - 1)) IS NOT NULL
ORDER BY A.ID,B.recursionCount
--Cleanup
DROP TABLE TableA
结果:
ID FieldA possible_guid actual_guid
----------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------------------------------------
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ index.cfm NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ fuseaction NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ content.page NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ nodeID NULL
1 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ index.cfm NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ fuseaction NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ content.page NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ nodeID NULL
2 /index.cfm/fuseaction/content.page/nodeID/18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD/ 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD 18156F6E-88E3-42FC-BDCB-DA6CBAD14EFD