根据列值组分隔符

时间:2015-05-11 08:27:25

标签: sql tsql sql-server-2012

拥有简单的数据源([ID][Value])我需要像这样计算名为[Group]的第三列:

enter image description here

规则很简单:

  1. ~符号与新组的开头匹配
  2. 数据永远不会以~符号开头或结尾(我~[ID] = 1的价值不会MAX([ID]) = 1
  3. 我不关心~符号的组值(可以为null,空字符串,数字等)
  4. 我想在简单选择中计算[Group]列值,但无法使用LAG函数执行此操作。我想知道有没有聪明的方法来做到这一点?

    以下是样本数据:

    DECLARE @DataSource TABLE
    (
        [ID] TINYINT
       ,[Value] CHAR(1)
    );
    
    INSERT INTO @DataSource ([ID], [Value])
    VALUES   (1,'A')
            ,(2,'A')
            ,(3,'A')
            ,(4,'~')
            ,(5,'A')
            ,(6,'A')
            ,(7,'A')
            ,(8,'~')
            ,(9,'A')
            ,(10,'A')
            ,(11,'~')
            ,(12,'A');
    
    SELECT [ID]
          ,[Value]
    FROM @DataSource;
    

1 个答案:

答案 0 :(得分:3)

使用OVERROWS窗口说明符,似乎很简单:

SELECT [ID]
      ,[Value]
      ,SUM(CASE WHEN Value = '~' THEN 1 ELSE 0 END) OVER
           (ORDER BY ID
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
       + 1 as [Group]
FROM @DataSource;

结果:

ID   Value Group
---- ----- -----------
1    A     1
2    A     1
3    A     1
4    ~     2
5    A     2
6    A     2
7    A     2
8    ~     3
9    A     3
10   A     3
11   ~     4
12   A     4

当然,逻辑是,可以通过询问“在此特定行之前发生了多少~这个问题来确定一个组号?” - 这会产生一个基于0的组号,所以我也加了一个。 OP不考虑为~行分配的值的灵活性意味着不需要特殊的套管逻辑。