带有累计计数的SQL中带分隔符的半冒号文本

时间:2017-08-25 05:05:20

标签: sql sql-server delimited

我有一张桌子

Program          FileCount
B1               1
A1;B2            2
A2;B3            1
A3;C1;B4         1
A3;C2;D1;B5;B6   3
C3;D2;B7         1
B8;B9            2
B8;B9            2

我只对程序B感兴趣,我想采取所有程序B

Program    FileCount
B1         1
B2         2  
B3         1  
B4         1
B5         3
B6         3
B7         1
B8         4
B9         4  

请注意:

  1. 我使用的是Microsoft SQL Server 2012
  2. 程序B的名称不统一,只有2位数但有所不同(例如,B1233456,B123)
  3. 我使用了下面的语法,但它没有给出我需要的东西。

    SELECT
    
    distinct CASE WHEN PATINDEX('%B%', Program)>0 THEN SUBSTRING(Program, PATINDEX('%B%', Program), 50) ELSE '' END as Program, 
    
    sum(cast (Filecount as integer)) as FileCount
    
    FROM dbo.Database1
    where Program like '%B%'
    group by Program
    

    非常感谢你们的帮助。

    亲切的问候,

    博纳亚阿迪

2 个答案:

答案 0 :(得分:1)

你走了。 Sql server 2016有一个新的split功能,可以在我使用ssf_split的地方使用。我的ssf_split函数返回一个表,其中一列名为Textline。

我希望很明显它已经迟到了。)

declare @t table (Program Varchar(max), Filecount integer)

insert into @t(Program ,   FileCount)
      select 'B1            ',   1
union all select 'A1;B2         ',   2
union all select 'A2;B3         ',   1
union all select 'A3;C1;B4      ',   1
union all select 'A3;C2;D1;B5;B6',   3
union all select 'C3;D2;B7      ',   1
union all select 'B8;B9         ',   2
union all select 'B8;B9         ',   2


select X.textline as Program, sum(t.filecount) as FileCount from @t t
Cross apply dbo.ssf_split(t.program,';') x where SUBSTRING(x.TextLine, 1,1) = 'b'
Group by x.TextLine
order by x.textline

将产生此输出:

Program                FileCount
---------------------- -----------
B1                     1
B2                     2
B3                     1
B4                     1
B5                     3
B6                     3
B7                     1
B8                     4
B9                     4

2016函数是STRING_SPLIT(字符串,分隔符),列名是Value。

所以用STRING_SPLIT和带有值的textline替换dbo.ssf_split,你应该很高兴。

答案 1 :(得分:1)

首先创建自定义拆分功能

        CREATE FUNCTION [dbo].[Split]
        (
            @String NVARCHAR(4000),
            @Delimiter NCHAR(1)
        )
        RETURNS TABLE 
        AS
        RETURN 
        (
            WITH Split(stpos,endpos) 
            AS(
                SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
                UNION ALL
                SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
                    FROM Split
                    WHERE endpos > 0
            )
            SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
                'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
            FROM Split
        )

您可以使用此查询进行选择:

    declare @t table (Program Varchar(max), Filecount integer)

    insert into @t(Program ,   FileCount)
    select 'B1 ',  1
    union all select 'A1;B2', 2
    union all select 'A2;B3', 1
    union all select 'A3;C1;B4', 1
    union all select 'A3;C2;D1;B5;B6', 3
    union all select 'C3;D2;B7', 1
    union all select 'B8;B9', 2
    union all select 'B81;B9', 2


    SELECT DISTINCT s.Data, t.Filecount
    FROM @t t
    CROSS APPLY dbo.Split(t.Program, ';') s
    WHERE Data like 'B%'