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 には、1 つではなく 2 つのグループにグループ化する必要がある同じデータが含まれているということです。

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

あなたが望むことをする通常の方法は、density_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 に答える
1

This will give you rankings on your columns. It will not give you 1,2,3 however. It will give you 1,3,6 etc based on how many in each grouping

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

See this SQLFiddle for a clearer idea of what I mean: http://sqlfiddle.com/#!3/0f201/2/0

于 2012-07-06T14:52:10.793 に答える