5

I am trying to add a Group column to a data set based on some criteria. For a simple example:

╔════╦══════╗
║ ID ║ DATA ║
╠════╬══════╣
║  1 ║   12 ║
║  2 ║   20 ║
║  3 ║    3 ║
║  4 ║   55 ║
║  5 ║   11 ║
╚════╩══════╝

Let's say our criteria is that the Data should be greater than 10. Then the result should be similar to:

╔════╦══════╦═══════╗
║ ID ║ DATA ║ GROUP ║
╠════╬══════╬═══════╣
║  1 ║   12 ║     1 ║
║  2 ║   20 ║     1 ║
║  3 ║    3 ║     2 ║
║  4 ║   55 ║     3 ║
║  5 ║   11 ║     3 ║
╚════╩══════╩═══════╝

So, all the rows that satisfied the criteria until an exception to the criteria occurred became part of a group. The numbering of the group doesn't necessarily need to follow this pattern, I just felt like this was a logical/simple numbering to explain the solution I am looking for.

4

2 回答 2

1

您可以通过查找数据 <= 10 的每一行来计算组标识符。然后,组标识符就是在给定行之前满足条件的行数。

select t.*,
       (select count(*)
        from t t2
        where t2.id <= t.id and
              t2.data <= 10
       ) as groupId
from t;

SQL Server 2012 具有累积和语法。该语句在该数据库中会更简单:

select t.*,
       sum(case when t2.data <= 10) over (order by id) as groupId
from t;

编辑:

以上没有考虑小于10的值在自己的组中。上面的逻辑是他们开始了一个新的组。

以下分配具有此约束的组 ID:

select t.*,
       ((select 2*count(*)
         from t t2
         where t2.id < t.id and
               t2.data <= 10
        ) + (case when t.id <= 10 then 1 else 0 end)
       ) as groupId
from t;
于 2013-09-09T18:36:06.327 回答
1

这可以通过递归查询轻松完成:

;WITH CTE 
     AS (SELECT *, 
                1 AS [GROUP] 
         FROM   TABLEB 
         WHERE  ID = 1 
         UNION ALL 
         SELECT T1.ID, 
                T1.DATA, 
                CASE 
                  WHEN T1.DATA < 10 THEN T2.[GROUP] + 1 
                  ELSE T2.[GROUP] 
                END [GROUP] 
         FROM   TABLEB T1 
                INNER JOIN CTE T2 
                        ON T1.ID = T2.ID + 1) 
SELECT * 
FROM   CTE 

可以在 上找到一个工作示例SQL Fiddle

祝你好运!

于 2013-09-09T18:42:04.917 回答