查找MySQL / MariaDB中的排名和项目总数

时间:2018-02-02 19:42:21

标签: mysql sql mariadb dense-rank

我有一个销售汇总表,如:

CREATE TABLE `sales_data` (
  `id` int(4) unsigned NOT NULL,
  `start_date` date NOT NULL,
  `end_date` date DEFAULT NULL,
  `store_sales` int(11) DEFAULT 0,
  PRIMARY KEY (`id`,`start_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

id列是产品ID,store_sales是本周的总商品销售额。

我希望根据销售额查找特定产品ID的排名,而不是销售总额,而是不同的商品。

到目前为止,我有:

SELECT FORMAT(tmp.rank, 0) AS rank, tmp.id, FORMAT(MAX(tmp.row_num), 0) AS total
FROM (
    SELECT 
        sd.id
        DENSE_RANK() OVER (ORDER BY SUM(sd.store_sales) DESC) AS rank,
        ROW_NUMBER() OVER (ORDER BY sd.id) AS row_num
    FROM sales_data sd
    WHERE sd.start_date >= '2017-01-01'
        AND sd.end_date <= '2017-05-15'
    GROUP BY sd.id
) AS tmp
WHERE tmp.id = 9233
LIMIT 1;

我认为问题是MAX(tmp.row_num)受外部查询中WHERE子句的限制,只需选择该单项的行号。

有没有办法在不运行子查询两次的情况下实现这一目标?

修改 这就是我对内部查询的看法:

rank,id,total
-------------------
1,4920,2
2,4043,3
3,3514,5
4,2425,7
5,4503,11
...

尽管这是所希望的:

rank,id,total
-------------------
1,4920,373
2,4043,373
3,3514,373
4,2425,373
5,4503,373
...

因此,我的外部查询可以选择WHERE id = 4043,我可以将其打印为Ranked {rank} out of {total},以便给我Ranked 2 out of 373

1 个答案:

答案 0 :(得分:0)

我相信DENSE_RANK()OVER(ORDER BY COUNT(sd.id)DESC)会做到这一点。

SELECT FORMAT(tmp.rank, 0) AS rank, tmp.id, FORMAT(tmp.row_num, 0) AS total
FROM (
    SELECT 
        sd.id
        DENSE_RANK() OVER (ORDER BY SUM(sd.store_sales) DESC) AS rank,
        DENSE_RANK() OVER (ORDER BY COUNT(sd.id) DESC) AS row_num
    FROM sales_data sd
    WHERE sd.start_date >= '2017-01-01'
        AND sd.end_date <= '2017-05-15'
    GROUP BY sd.id
) AS tmp
WHERE tmp.id = 92338
LIMIT 1