我正在使用第三方应用程序,该应用程序需要街道名称的备用名称列表。开发人员提供了一个生成列表的Python脚本,但生成所需的时间非常糟糕。我要做的是创建一个查询或存储过程,它将为街道名称创建所有不同的组合,并为每个名称维护JOINID。 这就是源的样子。
JOINID StreetName
147 PAULSON RD
165 NORTH AVE
270 E SCHOOL RD
212 OAKWOOD AVE
结果如下:
JOINID StreetName
147 PAULSON
147 PAULSON RD
165 NORTH
165 NORTH AVE
270 SCHOOL
270 E SCHOOL
270 SCHOOL RD
270 E RD
270 E SCHOOL RD
212 OAKWOOD
212 OAKWOOD AVE
结果将排除单个RD或其他道路类型等值。
这是我正在使用的当前查询。这将返回包含相应ID
的拆分列表'SELECT
JOINID, Split.a.value('.', 'VARCHAR(100)') AS Streetname
FROM
SELECT JOINID, CAST('<M>' + REPLACE([StreetName], ' ', '</M><M>') + </M>'
AS XML) AS CVS FROM [L].[ROADCENTERLINESHF]) AS A CROSS APPLY
CVS.nodes('/M') AS Split(a)`
任何建议都会很棒。 感谢
答案 0 :(得分:0)
你可以从一个函数开始,将每个字符串分成一个表/值和序列列表。然后从这些结果中,将所有值插入临时表并从该表开始查询。
CREATE function [dbo].[Split](
@String nvarchar (max),
@Delimiter nvarchar (200)
)
returns @ValueTable table (
[id] int IDENTITY(0,1),
[Value] nvarchar(max)
)
begin
declare @NextString nvarchar(max)
declare @Pos int
declare @NextPos int
declare @CommaCheck nvarchar(1)
--Initialize
set @NextString = ''
set @CommaCheck = right(@String,1)
--Check for trailing Comma, if not exists, INSERT
--if (@CommaCheck <> @Delimiter )
set @String = @String + @Delimiter
--Get position of first Comma
set @Pos = charindex(@Delimiter,@String)
set @NextPos = 1
--Loop while there is still a comma in the String of levels
while (@pos <> 0)
begin
set @NextString = substring(@String,1,@Pos - 1)
insert into @ValueTable ([Value]) Values (@NextString)
set @String = substring(@String,@pos +1,len(@String))
set @NextPos = @Pos
set @pos = charindex(@Delimiter,@String)
end
return
end
这是注释中提到的moden split函数的一个版本,它还包含一个序数。 `
--select * from dbo.SplitStrings_Moden('The quick brown fox jumped over the lazy dog.', ' ', 0)
--select * from dbo.SplitStrings_Moden('The quick brown fox jumped over the lazy dog.', ' ', 1)
CREATE FUNCTION dbo.SplitStrings_Moden
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255),
@RemoveEmptyEntries BIT = 1
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
WITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
E2(N) AS (SELECT 1 FROM E1 a, E1 b),
E4(N) AS (SELECT 1 FROM E2 a, E2 b),
E42(N) AS (SELECT 1 FROM E4 a, E2 b),
cteTally(N) AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1)))
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42),
cteStart(N1) AS (SELECT t.N+1 FROM cteTally t
WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0))
SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000)), ROW_NUMBER() OVER (ORDER BY N1) ordinal
FROM cteStart s
WHERE (SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000)) <> ''
OR
@RemoveEmptyEntries = 0
);
`