添加row_number会影响汇总中的行顺序

时间:2010-12-06 04:17:14

标签: sql-server sql-server-2008

我有以下内容:

CREATE TABLE food_delivery
(
    foodtype varchar(50) NOT NULL,
    foodname varchar(50) NOT NULL,
    numitems int NOT NULL
)
go

INSERT INTO food_delivery
VALUES 
('vegetable', 'carrot', 30), 
('vegetable', 'carrot', 50), 
('vegetable', 'potato', 40),
('vegetable', 'potato', 60),
('fruit', 'apple', 50),
('fruit', 'apple', 70),
('fruit', 'banana', 60),
('fruit', 'banana', 80)
GO

现在,当我运行此查询时:

SELECT foodtype, foodname, SUM(numitems)
FROM food_delivery
GROUP BY foodtype, foodname WITH ROLLUP

我明白了:

foodtype     foodname     
------------ ------------ -----------
fruit        apple        120
fruit        banana       140
fruit        NULL         260
vegetable    carrot       80
vegetable    potato       100
vegetable    NULL         180
NULL         NULL         440

我很满意这个订单,但我也希望为每种食物类型中的项目添加排名,以便我有这样的事情:

foodtype     foodname                 
------------ ------------ ----------- --------------------
fruit        apple        120         1
fruit        banana       140         2
fruit        NULL         260         3
vegetable    carrot       80          1
vegetable    potato       100         2
vegetable    NULL         180         3
NULL         NULL         440         1

我的想法是,我想识别排名为1的行并对它们进行不同的处理。

所以这是我使用的查询:

SELECT foodtype, foodname, SUM(numitems), 
         ROW_NUMBER() OVER (PARTITION BY foodtype ORDER BY foodname, SUM(numitems))
FROM food_delivery
GROUP BY foodtype, foodname WITH ROLLUP

不幸的是,添加ROW_NUMBER()完全抛出了我的结果集的排序,我得到了这个:

foodtype     foodname                 
------------ ------------ ----------- --------------------
NULL         NULL         440         1
fruit        NULL         260         1
fruit        apple        120         2
fruit        banana       140         3
vegetable    NULL         180         1
vegetable    carrot       80          2
vegetable    potato       100         3

即。摘要位于每个组的顶部而不是底部。

有人能告诉我如何在每个小组的底部获取我的摘要,同时仍然有我的排名

感谢。


编辑:所以Jon Seigel的答案给了我我想要的东西,但我仍然不明白为什么其他解决方案不起作用。

拿这个:

SELECT  CASE WHEN foodtype IS NULL THEN 0 ELSE 1 END,
        foodtype,  
        CASE WHEN foodname IS NULL THEN 0 ELSE 1 END,
        foodname,  
        SUM(numitems),   
        ROW_NUMBER() OVER (PARTITION BY foodtype 

ORDER BY    CASE WHEN foodtype IS NULL THEN 0 ELSE 1 END, 
            foodtype, 
            CASE WHEN foodname IS NULL THEN 0 ELSE 1 END, 
            foodname DESC)  RankVal 

FROM    food_delivery  
GROUP BY    foodtype,  
            foodname WITH ROLLUP  

ORDER BY    CASE WHEN foodtype IS NULL THEN 0 ELSE 1 END, 
            foodtype, 
            CASE WHEN foodname IS NULL THEN 0 ELSE 1 END, 
            foodname DESC

这与Jon的解决方案几乎完全相同,只是我将订单设为降序,并将 1 0 转置于< strong>那么0 ELSE 1 。在我看来,这应该给我相同的结果(即NULLS将为0,因为它们被排序为DESC,它们应该出现在集合的底部)。然而,返回的结果集是:

            foodtype                 foodname                 RankVal
----------- ------------ ----------- ------------ ----------- --------------------
0           NULL         0           NULL         440         1
1           fruit        0           NULL         260         1
1           fruit        1           banana       140         2
1           fruit        1           apple        120         3
1           vegetable    0           NULL         180         1
1           vegetable    1           potato       100         2
1           vegetable    1           carrot       80          3

如您所见,CASE语句的结果未按DESCending顺序排序。

2 个答案:

答案 0 :(得分:1)

尝试明确指定ORDER BY

这样的东西
SELECT  foodtype, 
        foodname, 
        SUM(numitems),  
        ROW_NUMBER() OVER (PARTITION BY foodtype ORDER BY foodname, SUM(numitems)) RankVal
FROM    @food_delivery 
GROUP BY    foodtype, 
            foodname WITH ROLLUP 

ORDER BY    CASE WHEN foodtype IS NULL THEN 1 ELSE 0 END,
            foodtype,
            CASE WHEN foodname IS NULL THEN 1 ELSE 0 END,
            foodname,
            RankVal

答案 1 :(得分:1)

SELECT
    foodtype,
    foodname,
    NumItems,
    ROW_NUMBER() OVER
    (
        PARTITION BY foodtype
        ORDER BY
            (CASE WHEN foodtype IS NULL THEN 1 ELSE 0 END),
            foodtype,
            (CASE WHEN foodname IS NULL THEN 1 ELSE 0 END),
            foodname
    ) AS Rank
    FROM
    (
        SELECT
            foodtype,
            foodname,
            SUM(numitems) AS NumItems
            FROM food_delivery
            GROUP BY foodtype, foodname WITH ROLLUP
    ) a
    ORDER BY
        (CASE WHEN foodtype IS NULL THEN 1 ELSE 0 END),
        foodtype,
        (CASE WHEN foodname IS NULL THEN 1 ELSE 0 END),
        foodname