首页 > 解决方案 > 更改与添加列 - 将月份中的所有日期设置为一个结束日期

问题描述

我正在尝试按销售额添加排名,并将日期列更改为“月末”字段,该字段每月有一个月的结束日期 - 如果这有意义吗?您会更改表格并添加列,还是仅重命名日期字段并使用 set 和 case 来使所有 3 月日期 = 3-31-18 和所有 4 月 4-30-18 日?我做到了这一点:

       UPDATE table1
        SET DATE=EOMONTH(DATE) AS MONTH_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 

我可以像这样连续做两组而不添加更新吗?我正在寻找每个月内的前 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 | Month End | SALES | Rank |
+------+-----------+-------+------+
|      |           |       |      |
|   37 | 3-31-18   |   100 |    1 |
|   38 | 3-31-18   |    65 |    2 |
|   39 | 4-30-18   |   500 |    1 |
|   40 | 4-30-18   |   199 |    2 |
+------+-----------+-------+------+

标签: sql-server

解决方案


根据您的预期输出,我认为这也可能有效。

create table Salesdate (Cust int, Dates date, Sales int) 

insert into Salesdate values 

(36 , '2018-03-05' ,    50  ) 
,(37 , '2018-03-15'  ,   100 ) 
,(38 , '2018-03-25'  ,   65  ) 
,(37 , '2018-04-05'   ,  95  ) 
,(40 , '2018-04-25'  ,   199 ) 
,(39 , '2018-04-21'  ,   500 ) 

将同一列日期更新到该月的最后一天(EOmonth 将有助于给出该月的最后一天),您可以添加单独的列或根据需要更新列。

Update Salesdate 
set Dates = eomonth(Dates) 

在表中添加一个名为 rank 的列。

Alter table Salesdate 
add rank int 

更新刚刚添加的列排名。

update Salesdate 
set Salesdate.[rank] =  tbl.Ranked from  
(select   Cust, Sales,  Dates ,  rank() over (Partition by Dates order by Sales Desc) 
Ranked from Salesdate ) tbl
where tbl.Cust = salesdate.Cust 
and tbl.Sales = salesdate.Sales 
and tbl.dates = salesdate.Dates 

--如果你希望你的决赛桌只有排名1和2,不确定这一步是否必要,那么你可以删除数据。或者它也可以仅在选择列表中被过滤掉。请注意,如果我们没有给定客户的唯一一组销售额,有时排名可能会跳过数字。

;With cte as ( 
select * from Salesdate) 

delete from cte
where [RANK] > 2  

select * from Salesdate 
order by dates, [RANK]  

输出

Cust    Dates   Sales   rank
37  2018-03-31  100      1
38  2018-03-31  65       2
39  2018-04-30  500      1
40  2018-04-30  199      2

推荐阅读