这在标题中很难解释,但这里有一张表:
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等等 - 大多数情况下都是黑暗中的刺伤)并且四处都是围墙。
编辑:另外一件事是我需要随机打破COUNT
的关系。因此,例如,如果COUNT
对于所有行都是0
,则返回的第一个组应该是随机的。我在下面的两个答案中都将NEWID()
添加到ORDER BY
,但没有运气,我试过这个。
谢谢。
答案 0 :(得分: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
编辑:
要在关联时进行随机化,您可以使用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
答案 1 :(得分: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 Fiddle