Добавление row_number влияет на порядок строк в свертке - PullRequest
2 голосов
/ 06 декабря 2010

У меня есть следующее:

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

т.е. Сводные данные находятся вверху каждой группы, а не внизу.

Может кто-нибудь сказать мне, как я могу получить свои резюме в нижней части каждой группы , сохраняя при этом мой рейтинг ?

Спасибо.


РЕДАКТИРОВАТЬ: Таким образом, ответ Джона Зигеля дает мне то, что я хочу, но я все еще не понимаю, почему другие решения не работают.

Возьми это:

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

Это почти идентично решению Джона, за исключением того, что у меня есть порядок по убыванию , и я транспонирую 1 и 0 в THEN 0 ИЛИ 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 ]

1 голос
/ 06 декабря 2010
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
1 голос
/ 06 декабря 2010

Попробуйте явно указать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...