SQL Server组合查询

时间:2016-02-22 21:41:24

标签: sql-server tsql

我正在使用第三方应用程序,该应用程序需要街道名称的备用名称列表。开发人员提供了一个生成列表的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)`

任何建议都会很棒。 感谢

1 个答案:

答案 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
          );

`