根据部分数据计算SQL排名

时间:2016-03-02 16:51:13

标签: sql-server tsql azure-sql-database

给出以下代表性样本表;

Id    SupplierID    Amount     Time
-----------------------------------------------------------------
1     1             99.50      2016-02-17 13:19:21.4107347 +00:00
2     1             99.00      2016-02-17 15:00:40.1052771 +00:00
3     2             98.00      2016-02-17 15:07:07.6283091 +00:00
4     1             95.00      2016-02-17 16:40:08.4895886 +00:00
5     3             94.50      2016-02-17 16:40:18.7326269 +00:00
6     2             92.00      2016-02-17 16:40:44.0902749 +00:00
-----------------------------------------------------------------

我想弄清楚表格中每条记录的每个供应商的排名 。因此,对于[Time]的每个实例,我想获得在该时间点或之前在表中有条目的每个供应商的记录,每个供应商都指示他们在该给定时间的排名。排名是[Amount],最低是第一。

因此,对于上面的例子,我希望的完整记录集如下:

Rank    SupplierID    Amount     Time
-----------------------------------------------------------------
1     1             99.50      2016-02-17 13:19:21.4107347 +00:00
1     1             99.00      2016-02-17 15:00:40.1052771 +00:00
1     2             98.00      2016-02-17 15:07:07.6283091 +00:00
2     1             98.00      2016-02-17 15:07:07.6283091 +00:00
1     1             95.00      2016-02-17 16:40:08.4895886 +00:00
2     2             95.00      2016-02-17 16:40:08.4895886 +00:00
1     3             94.50      2016-02-17 16:40:18.7326269 +00:00
2     1             94.50      2016-02-17 16:40:18.7326269 +00:00
3     2             94.50      2016-02-17 16:40:18.7326269 +00:00
1     2             92.00      2016-02-17 16:40:44.0902749 +00:00
2     3             92.00      2016-02-17 16:40:44.0902749 +00:00
3     1             92.00      2016-02-17 16:40:44.0902749 +00:00
-----------------------------------------------------------------

表中可能有任意数量的[SupplierId],此示例仅显示三个。

到目前为止,我会包含我的查询尝试,但我已经花了大约8个小时就完成了这项工作,并且没有提出任何正常的事情。我想避免使用动态SQL,我觉得有一个CTE或新的V12(SQL Server 2014等效)表达式可能会这样做,但我还是找不到它。或者它可能只是一个我看不到的基本交叉连接。 (我有点希望写出来可能会激发我的天赋,但没有快乐)。

我已经完成了我的尽职调查并阅读了使用动态语句和窗口函数的递归CTE,数据透视表,但我没有取得任何进展,所以任何帮助或指针都会非常受欢迎。

1 个答案:

答案 0 :(得分:1)

动臂。使用子查询进行管理。希望这对你有用!

select rank() over(partition by t.time order by r.amount) as [Rank],
r.supplierid, t.amount, r.amount as supplieramount, t.[time] from (
    select yt1.id, max(yt2.id) as lastamount
    from #yourtable yt1
    inner join #yourtable yt2 on yt2.id <= yt1.id
    group by yt1.id, yt2.supplierid
    ) as d
inner join #yourtable t on t.id = d.id
inner join #yourtable r on r.id = d.lastamount
order by t.id, r.amount