按具有多个层次级别的值对行进行排序
Sorting rows at value with multiple hierarchical levels
我有一个分层产品价格列表,其价格已经汇总。层级为 cluster、store 和 shelf.
我想对这些产品价格进行分层排序。每个级别都需要排序。这是预期结果的示例:
现在,我可以在货架级别对价格进行排序,但还不能在商店或集群级别排序:
SELECT cluster_id, store_id, shelf_id, price FROM (
SELECT * FROM (
SELECT p.*,
ROW_NUMBER () OVER (
ORDER BY
cluster_id ASC NULLS FIRST,
store_id ASC NULLS FIRST,
price DESC
) AS rn
FROM (SELECT * FROM products) p
)
)
ORDER BY rn;
我的实际结果是:
我正在使用 Oracle Database 12c。
示例数据
CREATE TABLE products (
cluster_id VARCHAR2(30),
store_id VARCHAR2(30),
shelf_id VARCHAR2(40),
price NUMBER(*,2)
);
INSERT INTO products VALUES ('10','230',NULL,120);
INSERT INTO products VALUES (NULL,NULL,NULL,500);
INSERT INTO products VALUES ('10','230','967',40);
INSERT INTO products VALUES ('10',NULL,NULL,300);
INSERT INTO products VALUES ('50','430','863',50);
INSERT INTO products VALUES ('50','170',NULL,70);
INSERT INTO products VALUES ('10','500','783',100);
INSERT INTO products VALUES ('50','170','798',20);
INSERT INTO products VALUES ('50','480',NULL,80);
INSERT INTO products VALUES ('50','430',NULL,50);
INSERT INTO products VALUES ('10','500',NULL,180);
INSERT INTO products VALUES ('50','480','486',60);
INSERT INTO products VALUES ('10','230','296',80);
INSERT INTO products VALUES ('50',NULL,NULL,200);
INSERT INTO products VALUES ('10','500','344',80);
INSERT INTO products VALUES ('50','480','234',20);
INSERT INTO products VALUES ('50','170','368',50);
我认为这会奏效。
with t as (
select cluster_id
, store_id
, shelf_id
, price
, row_number() over (partition by cluster_id order by price desc) cluster_sort
, row_number() over (partition by cluster_id, store_id order by price desc) store_sort
, row_number() over (partition by cluster_id, store_id, shelf_id order by price desc) shelf_sort
)
select cluster_id
, store_id
, shelf_id
, price
from t
order by cluster_sort
, store_sort
, shelf_sort
;
这种排序方法给出了所需的输出:
select p.*
from products p
order by
sum(case when store_id is not null and shelf_id is not null then price end)
over (partition by cluster_id) desc,
sum(case when store_id is not null and shelf_id is not null then price end)
over (partition by cluster_id, store_id) desc,
case when shelf_id is null then 1 end, price desc
我有一个分层产品价格列表,其价格已经汇总。层级为 cluster、store 和 shelf.
我想对这些产品价格进行分层排序。每个级别都需要排序。这是预期结果的示例:
现在,我可以在货架级别对价格进行排序,但还不能在商店或集群级别排序:
SELECT cluster_id, store_id, shelf_id, price FROM (
SELECT * FROM (
SELECT p.*,
ROW_NUMBER () OVER (
ORDER BY
cluster_id ASC NULLS FIRST,
store_id ASC NULLS FIRST,
price DESC
) AS rn
FROM (SELECT * FROM products) p
)
)
ORDER BY rn;
我的实际结果是:
我正在使用 Oracle Database 12c。
示例数据
CREATE TABLE products (
cluster_id VARCHAR2(30),
store_id VARCHAR2(30),
shelf_id VARCHAR2(40),
price NUMBER(*,2)
);
INSERT INTO products VALUES ('10','230',NULL,120);
INSERT INTO products VALUES (NULL,NULL,NULL,500);
INSERT INTO products VALUES ('10','230','967',40);
INSERT INTO products VALUES ('10',NULL,NULL,300);
INSERT INTO products VALUES ('50','430','863',50);
INSERT INTO products VALUES ('50','170',NULL,70);
INSERT INTO products VALUES ('10','500','783',100);
INSERT INTO products VALUES ('50','170','798',20);
INSERT INTO products VALUES ('50','480',NULL,80);
INSERT INTO products VALUES ('50','430',NULL,50);
INSERT INTO products VALUES ('10','500',NULL,180);
INSERT INTO products VALUES ('50','480','486',60);
INSERT INTO products VALUES ('10','230','296',80);
INSERT INTO products VALUES ('50',NULL,NULL,200);
INSERT INTO products VALUES ('10','500','344',80);
INSERT INTO products VALUES ('50','480','234',20);
INSERT INTO products VALUES ('50','170','368',50);
我认为这会奏效。
with t as (
select cluster_id
, store_id
, shelf_id
, price
, row_number() over (partition by cluster_id order by price desc) cluster_sort
, row_number() over (partition by cluster_id, store_id order by price desc) store_sort
, row_number() over (partition by cluster_id, store_id, shelf_id order by price desc) shelf_sort
)
select cluster_id
, store_id
, shelf_id
, price
from t
order by cluster_sort
, store_sort
, shelf_sort
;
这种排序方法给出了所需的输出:
select p.*
from products p
order by
sum(case when store_id is not null and shelf_id is not null then price end)
over (partition by cluster_id) desc,
sum(case when store_id is not null and shelf_id is not null then price end)
over (partition by cluster_id, store_id) desc,
case when shelf_id is null then 1 end, price desc