1

我正在尝试按顺序对数据进行分组。假设我有下表:

| 1 | A |
| 1 | A |
| 1 | B |
| 1 | B |
| 1 | C |
| 1 | B |

我需要 SQL 查询来输出以下内容:

| 1 | A | 1 |
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | B | 2 |
| 1 | C | 3 |
| 1 | B | 4 |

最后一列是在每个组中递增的组号。需要注意的重要一点是,第 3、4 和 5 行包含相同的数据,这些数据应分为 2 组而不是 1 组。

4

3 回答 3

2

对于MSSQL2008

假设您有一个 SampleStatuses 表:

Status  Date
A       2014-06-11
A       2014-06-14
B       2014-06-25
B       2014-07-01
A       2014-07-06
A       2014-07-19
B       2014-07-21
B       2014-08-13
C       2014-08-19

你写了以下内容:

;with
cte as (
    select top 1 RowNumber, 1 as GroupNumber, [Status], [Date] from SampleStatuses order by RowNumber
    union all
    select c1.RowNumber,
        case when c2.Status <> c1.Status then c2.GroupNumber + 1 else c2.GroupNumber end as  GroupNumber, c1.[Status], c1.[Date] 
    from cte c2 join SampleStatuses c1 on c1.RowNumber = c2.RowNumber + 1       
)
select * from cte;

你得到这个结果:

RowNumber   GroupNumber Status  Date
1           1           A       2014-06-11
2           1           A       2014-06-14
3           2           B       2014-06-25
4           2           B       2014-07-01
5           3           A       2014-07-06
6           3           A       2014-07-19
7           4           B       2014-07-21
8           4           B       2014-08-13
9           5           C       2014-08-19
于 2014-09-16T13:17:57.403 回答
1

这将为您提供列上的排名。但是,它不会给您 1,2,3。它会根据每个分组的数量为您提供 1、3、6 等

select 
a,
b,
rank() over (order by a,b)
 from
table1

请参阅此 SQLFiddle 以更清楚地了解我的意思:http ://sqlfiddle.com/#!3/0f201/2/0

于 2012-07-06T14:52:10.793 回答
1

你会做你想做的正常方式是dense_rank函数:

select key, val,
       dense_rank() over (order by key, val)
from t

然而,这并没有解决分离最后一组的问题。

为了处理这个问题,我必须假设有一个“id”列。SQL 中的表没有排序,所以我需要排序。如果您使用的是 SQL Server 2012,那么您可以使用 lag() 函数来获取您需要的内容。使用滞后来查看键、val 对在连续行上是否相同:

with t1 as (
     select id, key, val,
            (case when key = lead(key, 1) over (order by id) and
                       val = lead(val, 1) over (order by id)
                  then 1
                  else 0
             end) as SameAsNext
     from t
    )
select id, key, val,
       sum(SameAsNext) over (order by id) as GroupNum
from t

如果没有 SQL Server 2012(具有累积总和),您必须执行自联接来识别每个组的开头:

select t.*,
from t left outer join
     t tprev
     on t.id = t2.id + 1 and t.key = t2.key and t.val = t2.val
where t2.id is null

有了这个,使用连接将组分配为最小 id:

select t.id, t.key, t.val,
       min(tgrp.id) as GroupId
from t left outer join
     (select t.*,
      from t left outer join
           t tprev
           on t.id = t2.id + 1 and t.key = t2.key and t.val = t2.val
      where t2.id is null
    ) tgrp
    on t.id >= tgrp.id

如果您希望这些是连续数字,则将它们放在子查询中并使用dense_rank()。

于 2012-07-06T15:07:34.910 回答