聚合顶部之外的行

时间:2015-10-06 20:23:07

标签: sql sql-server aggregate sql-server-2014

假设我们有以下水果表:

Fruit   | Qty
-------------
Apple   | 2
Apple   | 5
Apple   | 2
Orange  | 3
Orange  | 4
Orange  | 0
Banana  | 2
Banana  | 5
Pear    | 2
Mango   | 1
Mango   | 0

如果我想获得前三名的成绩,我会创建一个这样的查询:

SELECT TOP 3 Fruit, SUM(Qty) AS Total
FROM Fruits
GROUP BY Fruit
ORDER BY Total DESC

将返回:

Apple   | 9
Orange  | 7
Banana  | 7

但是,如果我想要包含不在前3名中的Fruit的总和,我将不得不写这样的东西以使用NOT IN排除前3个水果:

SELECT 'OTHER' AS Fruit, SUM(Qty) AS Total
FROM Fruits
WHERE Fruit NOT IN (SELECT Fruit FROM (SELECT TOP 3 Fruit, SUM(Qty) AS Total FROM Fruits GROUP BY Fruit ORDER BY Total DESC) AS Test)

如果我想在一个查询中执行此操作,我想我可以使用UNION组合这两个查询。我已经有了我的计划B,但我想知道SQL是否有任何内置的方法来聚合行,这些行不是可用于简化查询的最高值的一部分?

3 个答案:

答案 0 :(得分:2)

您需要对总和进行RANK并为最终结果添加另一个SUM:

import pygame

from pygame.locals import *
from sys import exit

background0 = 'Screens\\Map\\Map01.jpg'
background1 = 'Screens\\Map\\Map02.jpg'
background2 = 'Screens\\Map\\Map03.jpg'
background3 = 'Screens\\Map\\Map04.jpg'
background4 = 'Screens\\Map\\Map05.jpg'
background5 = 'Screens\\Map\\Map06.jpg'
background6 = 'Screens\\Map\\Map07.jpg'
background7 = 'Screens\\Map\\Map08.jpg'
background8 = 'Screens\\Map\\Map09.jpg'
background9 = 'Screens\\Map\\Map10.jpg'
background10 = 'Screens\\Map\\Map11.jpg'
background11 = 'Screens\\Map\\Map12.jpg'
background12 = 'Screens\\Map\\Map13.jpg'
background13 = 'Screens\\Map\\Map14.jpg'
background14 = 'Screens\\Map\\Map15.jpg'
background15 = 'Screens\\Map\\Map16.jpg'
background16 = 'Screens\\Map\\Map17.jpg'
background17 = 'Screens\\Map\\Map18.jpg'
background18 = 'Screens\\Map\\Map19.jpg'

ground = [ background0, background1, background2, background3, background4, background5,
background6, background7, background8, background9, background10, background11,
background12, background13, background14, background15, background16, background17,
background18]
mouse_image = 'pygame\\Pygame_HW\\fugu.png'

new_resolution_x = 1000
new_resolution_y = 760

scale_x = new_resolution_x / 16120.0
scale_y = new_resolution_y / 19000.0

pic_wid = 16120 * scale_x
pic_height = 1000 * scale_y

pygame.init()

screen = pygame.display.set_mode((new_resolution_x, new_resolution_y), 0, 16)
pygame.display.set_caption("Hello World!")


for i in range(19):
    ground[i] = pygame.image.load(ground[i])
    ground[i] = pygame.transform.scale(ground[i], (int(pic_wid), int(pic_height)))


 mouse_cursor = pygame.image.load(mouse_image).convert_alpha()

while True:

for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        exit()

screen.fill((0, 0, 0))
for i in range(19):

    screen.blit(ground[i], (0,i * int(pic_height)))

x, y = pygame.mouse.get_pos()
x -= mouse_cursor.get_width() / 2
y -= mouse_cursor.get_height() / 2
screen.blit(mouse_cursor, (x, y))

pygame.display.update()

请参阅Fiddle

答案 1 :(得分:0)

这是通过基于sum(qty)对行进行排名来实现此目的的一种方法。

with totals as (SELECT Fruit, SUM(Qty) AS Total FROM Fruits GROUP BY Fruit)
, rownums as (select *, dense_rank() over(order by total desc) as rank from totals)
select 
case when rank > 3 then 'Other' else fruit end as fruit, total
from rownums

如果other行需要汇总,请在sum列中添加一个total,在group by语句中添加case

答案 2 :(得分:0)

几乎!,很遗憾你不能把RANK放进去!但你不能。所以你必须有一个嵌套的选择,然后是一个。

使用此方法,您可以获得任何您想要的组,即0和3之间..> 3 .. IN(1,3,6)等

DECLARE @Fruits TABLE (Fruit NVARCHAR(32),Qty INT)
INSERT INTO @Fruits(Fruit,Qty)
VALUES
('Apple',2),
('Apple',5),
('Apple',2),
('Orange',3),
('Orange',4),
('Orange',0),
('Banana',2),
('Banana',5),
('Pear',2),
('Mango',1),
('Mango',0)

SELECT TOP 3 Fruit, SUM(Qty) AS Total
FROM @Fruits
GROUP BY Fruit
ORDER BY Total DESC

SELECT A.Fruit,A.Total FROM
(
    SELECT Fruit, SUM(Qty) AS Total,RANK() OVER (ORDER BY SUM(Qty) DESC,Fruit) AS GroupNumber
    FROM @Fruits
    GROUP BY Fruit
) AS A
WHERE GroupNumber > 3 --This bit lets you pick the groups!
ORDER BY Total DESC