2

これをタイトルで説明するのは非常に困難でしたが、ここに私が持っている表があります。

CATEGORY_ID   COUNT   GROUPING
1             130     H
2              54     B
3             128     C
4              70     D
5              31     E
6              25     F
7              64     A
8              59     F
9              66     B
10             62     E
11            129     C
12             52     G
13             27     A
14            102     A
15            101     C

を取得するためのクエリを作成しようとしていますTOP 5 CATEGORY_ID。最初は全体的に並べ替えられますCOUNTが、そのグループに基づいて、CATEGORY_IDそのグループに関係なく、そのグループ内の他の を使用しCOUNTます。したがって、このルールに基づいて上記を実行したい場合TOP 5(おそらく説明が不十分である可能性があります)、私の結果は次のようになります。

CATEGORY_ID   COUNT   GROUPING
6             25      F <-- THE LOWEST COUNT OVERALL
8             59      F <-- THE NEXT LOWEST IN GROUP 'F'
13            27      A <-- THE NEXT LOWEST OVERALL
7             64      A <-- THE NEXT LOWEST IN GROUP 'A'
14            102     A <-- THE NEXT LOWEST IN GROUP 'A'

私はここや他の場所をよく見て (RANK()、DENSE_RANK()、GROUPING SETS などを試してみました - 主に暗闇の中での刺し傷として)、壁にぶつかりました。

編集:もう1つのことは、COUNTランダムに関係を断ち切る必要があることです。たとえば、COUNT0すべての行の場合、最初に返されるグループはランダムになります。以下の両方の回答に追加NEWID()してこれを試しましたが、うまくいきませんでした。ORDER BY

ありがとうございました。

4

2 に答える 2

5
; with groups as (
  select
    grouping,
    min(count) as group_min
  from categories
  group by grouping
)
select top 5 c.category_id, c.count, c.grouping
from categories c
join groups g on c.grouping = g.grouping
order by g.group_min, c.count

SQLフィドル

編集:

同点の場合にランダム化するには、 and を使用して各グループにランダムな順序を追加できrow_number()ますnewid()

; with groups as (
  select
    grouping,
    row_number() over (order by newid()) as random,
    min(count) as group_min
  from categories
  group by grouping
)
select top 5
  c.category_id, c.count, c.grouping
from categories c
join groups g on c.grouping = g.grouping
order by g.group_min, g.random, c.count

SQLフィドル

于 2013-01-29T19:38:31.973 に答える
2

更新:RANK()の代わりに使用するROW_NUMBER()ため、同点のレコード (すべてのカウントが 0 の場合など) は同じランキングになります。これにより、NEWID()ランダムな結果を得るために並べ替えることができます。

;WITH CatByCount AS (
    SELECT 
        CATEGORY_ID, 
        COUNT,
        GROUPING,
        RANK() OVER (ORDER BY COUNT) AS ORD
    FROM theTaBle
)
SELECT TOP 5 CATEGORY_ID, COUNT, GROUPING 
FROM (
    SELECT I.CATEGORY_ID, O.ORD, I.COUNT, I.GROUPING
    FROM CatByCount O
    CROSS APPLY (
        SELECT A.CATEGORY_ID, A.COUNT, A.GROUPING
        FROM theTable A
        WHERE A.GROUPING = O.GROUPING
    ) I
) X
ORDER BY X.ORD, X.COUNT, NEWID()

更新されたSQL フィドル

于 2013-01-29T19:43:51.060 に答える