在SQL Server 2012中横摇周期排名

问题描述 投票:1回答:1

我有一个表“T”的列“日期”,“北京时间”,“价格”,“值”。

    declare @t table (
    Date date
    , Ticker varchar(10)
    , price decimal(10, 2)
    , value decimal (10 ,2)
)

insert into @t values
('20130101', 'ABC', '100.00', '55000')
,('20130102', 'ABC', '101.50', '40600')
,('20130103', 'ABC', '99.80', '109780' )
,('20130104', 'ABC', '95.50', '68760'  )
,('20130105', 'ABC', '78.00', '58500')
,('20130101', 'JKL', '34.57', '34570')
,('20130102', 'JKL', '33.99', '54384')
,('20130103', 'JKL', '31.85', '12740')
,('20130104', 'JKL', '30.11', '63231')
,('20130105', 'JKL', '35.00', '59500')
,('20130101', 'XYZ', '11.50', '34500')
,('20130102', 'XYZ', '12.10', '21296')
,('20130103', 'XYZ', '17.15', '10290')
,('20130104', 'XYZ', '14.10', '32430')
,('20130105', 'XYZ', '15.55', '12129')


SELECT *,

[Value] / nullif (price,0) AS Qty

FROM @t t

我计算“数量” =“值” /“价格”

Date    Ticker  price   value   Qty
2013-01-01  ABC 100.00  55000.00    550.0000000000000
2013-01-02  ABC 101.50  40600.00    400.0000000000000
2013-01-03  ABC 99.80   109780.00   1100.0000000000000
2013-01-04  ABC 95.50   68760.00    720.0000000000000
2013-01-05  ABC 78.00   58500.00    750.0000000000000
2013-01-01  JKL 34.57   34570.00    1000.0000000000000
2013-01-02  JKL 33.99   54384.00    1600.0000000000000
2013-01-03  JKL 31.85   12740.00    400.0000000000000
2013-01-04  JKL 30.11   63231.00    2100.0000000000000
2013-01-05  JKL 35.00   59500.00    1700.0000000000000
2013-01-01  XYZ 11.50   34500.00    3000.0000000000000
2013-01-02  XYZ 12.10   21296.00    1760.0000000000000
2013-01-03  XYZ 17.15   10290.00    600.0000000000000
2013-01-04  XYZ 14.10   32430.00    2300.0000000000000
2013-01-05  XYZ 15.55   12129.00    780.0000000000000

我想计算数量上滚动3天的百分等级为每个订单。

试图从Excel中复制这样的输出:

Date      Ticker  price     value   Qty 3d_rank
01/01/13    ABC  100.00     55000   550 
01/02/13    ABC  101.50     40600   400 
01/03/13    ABC   99.80    109780  1100   1
01/04/13    ABC   95.50     68760   720   2
01/05/13    ABC   78.00     58500   750   2
01/01/13    JKL   34.57     34570  1000 
01/02/13    JKL   33.99     54384  1600 
01/03/13    JKL   31.85     12740   400   3
01/04/13    JKL   30.11     63231  2100   1
01/05/13    JKL   35.00     59500  1700   2
01/01/13    XYZ   11.50     34500  3000 
01/02/13    XYZ   12.10     21296  1760 
01/03/13    XYZ   17.15     10290   600   3
01/04/13    XYZ   14.10     32430  2300   1
01/05/13    XYZ   15.55     12129   780   2

难道我用的排名,PERCENT_RANK?

sql-server-2012 rank percentile
1个回答
1
投票

(编辑我以前的答案 - 现在CTE是程序的一部分。)

CREATE FUNCTION fRollingRank (@startDate date, @noOfDays int)
RETURNS @resultsTable TABLE 
(dateCol date,
ticker varchar(10),
price decimal(10,2),
valueCol decimal(10,2),
Qty decimal(10,2),
threeDays_rank varchar(1))

AS
BEGIN
--end od the desired period
DECLARE @endDate date = DATEADD(day, @noOfDays-1, @startDate);

--CTE performing the calculations
WITH qtyTable AS (
SELECT *, ValueCol / NULLIF (price,0) AS Qty 
FROM  t), --replace t with the name of your table

rankTable AS (
SELECT DateCol, Ticker, RANK() OVER (PARTITION BY Ticker ORDER BY Qty DESC) AS threeDays_rank 
FROM qtyTable 
WHERE DateCol BETWEEN @startDate AND @endDate)

--inserting result into output variable
INSERT INTO @resultsTable
SELECT qt.DateCol, qt.Ticker, qt.price, qt.valueCol, CAST(qt.Qty AS decimal(9,2)) AS Qty, ISNULL(CAST(rt.threeDays_rank AS varchar(1)), '') AS threeDays_rank 
FROM qtyTable qt LEFT JOIN rankTable rt 
ON qt.Ticker=rt.Ticker AND rt.DateCol=qt.DateCol;

--calling variable to output
RETURN
END;
GO

然后你只需要使用的功能:

--using function with input parameters
SELECT * FROM fRollingRank ('2013-01-01', 2)
ORDER BY Ticker, DateCol;

这部分仍然有效:

除了 - 尽量避免使用保留字,如日期或值,或者使用以数字开头的名字命名列。

© www.soinside.com 2019 - 2024. All rights reserved.