-1

我无法按月对顶级客户进行排名。我创建了一个新的排名列 - 但如何按月分解?任何帮助请。代码和表格如下:

排名的逻辑是从表中选择每月前两名的客户。还包含在代码中(至少尝试过)是重命名日期字段并将其设置为仅反映月末日期。

 SELECT * FROM table1;
UPDATE table1
SET DATE=EOMONTH(DATE) AS MO_END;
ALTER TABLE table1
ADD COLUMN RANK INT AFTER SALES;
UPDATE table1
SET RANK=
RANK() OVER(PARTITION BY cust ORDER BY sales DESC);
LIMIT 2

开始于

------+----------+-------+--+
| CUST |   DATE   | SALES |  |
+------+----------+-------+--+
|   36 | 3-5-2018 |    50 |  |
|   37 | 3-15-18  |   100 |  |
|   38 | 3-25-18  |    65 |  |
|   37 | 4-5-18   |    95 |  |
|   39 | 4-21-18  |   500 |  |
|   40 | 4-45-18  |   199 |  |
+------+----------+-------+--+

期望的最终结果

+------+---------+-------+------+--+
| CUST | MO_END  | SALES | RANK |  |
+------+---------+-------+------+--+
|   37 | 3-31-18 |   100 |    1 |  |
|   38 | 3-25-18 |    65 |    2 |  |
|   39 | 4-30-18 |   500 |    1 |  |
|   40 | 4-45-18 |   199 |    2 |  |
+------+---------+-------+------+--+
4

1 回答 1

0

作为一个简单的选择:

select * 
from   (
    select
          table1.*
        , DENSE_RANK() OVER(PARTITION BY cust, EOMONTH(DATE) ORDER BY sales DESC) as ranking
    from table1
    )
where ranking < 3
;

如果存储很重要:我不会使用 [rank] 作为列名,因为我避免使用 SQL 中使用的任何单词,可能是 [sales_rank] 或类似的。

with cte as (
    select
          cust
        , DENSE_RANK() OVER(PARTITION BY cust, EOMONTH(DATE) ORDER BY sales DESC) as ranking
    from table1
    )
update cte
set sales_rank = ranking
where ranking < 3
;

确实没有理由存储月末,只需在over()子句的分区中使用该函数即可。

顺便说一句,LIMIT 2 不是可以在 SQL Server 中使用的东西,而且肯定不能“按分组”使用。当您使用“窗口函数”时,rank()dense_rank()可以使用下一个“层”的 where 子句中的输出。即在子查询(或 cte)中使用这些函数,然后使用 where 子句按计算值过滤行。

另请注意,我曾经dense_rank()保证不会跳过任何排名数字,以便后续的 where 子句有效。

于 2018-11-19T02:54:20.153 回答