2017-06-08 29 views

回答

0

你可以使用拆分功能APPLY這樣

DECLARE @SampleData AS TABLE 
(
    numbers varchar(200) 
) 

INSERT INTO @SampleData 
VALUES ('1000-1050, 1054, 1090-1230, 1245') 

;WITH temp AS 
(
    SELECT 1 AS Number 
    UNION ALL 
    SELECT t.Number + 1 FROM temp t 
    WHERE t.Number < 5000 
) -- return table from 1 --> 5000 
SELECT DISTINCT 
     ca2.* 
FROM @SampleData sd 
CROSS APPLY 
(
    SELECT pos, LTRIM(Value) AS Value 
    FROM dbo.SplitString(sd.Numbers,',') 
) ca1 
CROSS APPLY 
(
    SELECT * 
    FROM temp t WHERE t.Number BETWEEN LEFT(ca1.[Value], charindex('-', ca1.[Value] + '-') - 1) AND 
          CASE 
          WHEN len(ca1.[Value]) < charindex('-', ca1.[Value] + '-') THEN ca1.[Value] 
          ELSE RIGHT(ca1.[Value], len(ca1.[Value]) - charindex('-', ca1.[Value] + '-')) 
          END 
) ca2 
OPTION (MAXRECURSION 0) 

Split函數

CREATE FUNCTION [dbo].[SplitString] (@Text varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return ( 
    Select Pos = Row_Number() over (Order By (Select null)) 
     ,Value = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
    From (Select x = Cast('<x>'+ Replace(@Text,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i) 
); 

演示鏈接:http://rextester.com/GIPGR78132

0

第一分割的逗號分隔的值,則得到使用遞歸公用表表達式的值。

Declare @values nvarchar(max) = '1000-1050, 1054, 1090-1230, 1245' 

;with ranges_cte as 
(
    select cast(case pos when 0 then ResultValue else left(ResultValue,pos-1) end as int) first, cast(case pos when 0 then ResultValue else substring(ResultValue,pos+1,len(ResultValue)-pos) end as int) Last 
    from (
    select ResultValue, charINDEx('-',ResultValue) pos 
    from dbo.SplitString(@values,',')) x 
) 
, values_rte as 
(
select first,last,first as active 
from ranges_cte 
union all 
select first,last,active +1 as active 
from values_rte 
where active< last 
) 

select * 
from values_rte 
OPTION (MAXRECURSION 0) 

功能分裂值:

Create FUNCTION [dbo].[SplitString] (@StringArray NVARCHAR(MAX), @Delimiter NVARCHAR(10)) 
RETURNS @ResultedValues table 
(
nr int, 
ResultValue nvarchar(max) 
) 
AS 
--select * from dbo.splitstring ('123,456,789',',') 
BEGIN 
    declare @string nvarchar(max) 
    declare @nr int = 1 
    set @string = @StringArray 
    WHILE (CHARINDEX(@Delimiter,@String)>0) 
    BEGIN 
    INSERT INTO @ResultedValues (nr,ResultValue) VALUES (@nr,LTRIM(RTRIM(SUBSTRING(@String,1,CHARINDEX(@Delimiter,@String)-1)))) 
    SET @String = SUBSTRING(@String, CHARINDEX(@Delimiter,@String)+LEN(@Delimiter),LEN(@String)) 
    set @nr = @nr +1 
    END 
INSERT INTO @ResultedValues (nr,ResultValue) VALUES (@nr, LTRIM(RTRIM(@String))) 
RETURN 
END 
0

創建分割功能:

CREATE FUNCTION [dbo].[SplitIDsTest] 
(
    @idList varchar(4000) 
) 
RETURNS @parsedList TABLE 
(
    Id varchar(50), 
    Nr int 
) 
AS 
BEGIN 

    DECLARE @id varchar(10), @pos int 
    DECLARE @nr int = 0; 

    SET @idList = LTRIM(RTRIM(@idList)) + ',' 
    SET @Pos = CHARINDEX(',', @idList)  

    IF REPLACE(@idList, ',', '') <> '' 
     BEGIN 
      WHILE @Pos > 0 
       BEGIN 
        SET @id = LTRIM(RTRIM(LEFT(@idList, @pos - 1))) 

        IF @id <> '' 
        BEGIN 
         set @nr += 1; 
         INSERT INTO @ParsedList (Id, Nr) 
         VALUES (@id, @nr); 
        END 

        SET @idList = RIGHT(@idList, LEN(@idList) - @pos) -- 'WMPC,' (inklusive Komma) links vom Eingabeparameter abschneiden, weil jetzt der nächste Wert gesucht wird 
        SET @pos = CHARINDEX(',', @idList, 1)    -- Nächste Position eines Kommas suchen und in der WHILE-Schleife weitermachen 
       END 
     END 

    RETURN 
END 

然後帳簿表:

select top 1000000 N=identity(int, 1, 1) 
    into dbo.Tally 
    from master.dbo.syscolumns a cross join master.dbo.syscolumns b; 

然後使用:

select distinct Tally.N 
    from SplitIDsTest('10-12, 34, 9') splitted 
    join Tally on 1 = case 
        when CHARINDEX('-', splitted.Id) > 0 then 
         case 
         when Tally.N between cast(left(splitted.Id, CHARINDEX('-', splitted.Id) - 1) as int) 
             and cast(right(splitted.Id, len(splitted.Id) - CHARINDEX('-', splitted.Id)) as int) then 1 
         else 0 
         end 
        when Tally.N = cast(splitted.Id as int) then 1 
        else 0 
        end 
order by Tally.N 
相關問題