指定长度的所有子串
all substrings of a specified length
我有一个 table,其中有一个长度可变的字符串列。我需要获取指定长度的单元格值的所有子串
示例:
094740
声明:
select ???(Column, 3) from table
结果为:
094
947
474
740
不用存储过程能实现吗
您可以尝试使用 CTE 递归和简单的数学公式来制作它。
CTE递归会得到一个结果集来表示语句偏移了多少行
查询 1:
declare @offset int = 3
;WITH CTE AS (
SELECT 0 startIndex, len(col) totalLen,col
FROM T
UNION ALL
SELECT startIndex + 1,totalLen,col
FROM CTE
WHERE startIndex <= totalLen - @offset
)
SELECT substring(col,startIndex, @offset)
FROM CTE
WHERE startIndex > 0
| |
|-----|
| 094 |
| 947 |
| 474 |
| 740 |
您有两个可能的选择 - 递归 CTE 或使用数字的语句 table:
Table:
SELECT *
INTO StringTable
FROM (VALUES ('094740'), ('1237')) v (StringColumn)
使用递归 CTE 的语句:
DECLARE @Length int = 3
;WITH rCTE AS (
SELECT 1 AS Position, t.StringColumn
FROM StringTable t
UNION ALL
SELECT r.Position + 1, r.StringColumn
FROM rCTE r
WHERE r.Position + @Length <= LEN(r.StringColumn)
)
SELECT StringColumn, SUBSTRING(StringColumn, Position, @Length) AS Substring
FROM rCTE
ORDER BY StringColumn, Position
使用数字 table 的语句(有 1000 行):
DECLARE @Length int = 3
;WITH NumberTable AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Rn
FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) a (n)
CROSS APPLY (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) b (n)
CROSS APPLY (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) c (n)
)
SELECT t.StringColumn, SUBSTRING(t.StringColumn, n.Rn, @Length) AS Substring
FROM StringTable t
JOIN Numbertable n ON (n.Rn + @Length - 1) <= LEN(t.StringColumn)
ORDER BY t.StringColumn, n.Rn
结果:
StringColumn Substring
----------------------
094740 094
094740 947
094740 474
094740 740
1237 123
1237 237
我有一个 table,其中有一个长度可变的字符串列。我需要获取指定长度的单元格值的所有子串
示例:
094740
声明:
select ???(Column, 3) from table
结果为:
094
947
474
740
不用存储过程能实现吗
您可以尝试使用 CTE 递归和简单的数学公式来制作它。
CTE递归会得到一个结果集来表示语句偏移了多少行
查询 1:
declare @offset int = 3
;WITH CTE AS (
SELECT 0 startIndex, len(col) totalLen,col
FROM T
UNION ALL
SELECT startIndex + 1,totalLen,col
FROM CTE
WHERE startIndex <= totalLen - @offset
)
SELECT substring(col,startIndex, @offset)
FROM CTE
WHERE startIndex > 0
| |
|-----|
| 094 |
| 947 |
| 474 |
| 740 |
您有两个可能的选择 - 递归 CTE 或使用数字的语句 table:
Table:
SELECT *
INTO StringTable
FROM (VALUES ('094740'), ('1237')) v (StringColumn)
使用递归 CTE 的语句:
DECLARE @Length int = 3
;WITH rCTE AS (
SELECT 1 AS Position, t.StringColumn
FROM StringTable t
UNION ALL
SELECT r.Position + 1, r.StringColumn
FROM rCTE r
WHERE r.Position + @Length <= LEN(r.StringColumn)
)
SELECT StringColumn, SUBSTRING(StringColumn, Position, @Length) AS Substring
FROM rCTE
ORDER BY StringColumn, Position
使用数字 table 的语句(有 1000 行):
DECLARE @Length int = 3
;WITH NumberTable AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Rn
FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) a (n)
CROSS APPLY (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) b (n)
CROSS APPLY (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) c (n)
)
SELECT t.StringColumn, SUBSTRING(t.StringColumn, n.Rn, @Length) AS Substring
FROM StringTable t
JOIN Numbertable n ON (n.Rn + @Length - 1) <= LEN(t.StringColumn)
ORDER BY t.StringColumn, n.Rn
结果:
StringColumn Substring
----------------------
094740 094
094740 947
094740 474
094740 740
1237 123
1237 237