在同一查询中选择特定时段的前5个最高高点和5分钟最低点,例如过去180天和30天

时间:2019-12-30 15:58:08

标签: sql sql-server tsql

以下是表格数据,需要找出同一查询中整个180天和最近30天的前5个最大最高价和最低最低价。

Stock  High Low Date        prevclose ....
------------------------------------
ABB    100   75  29/12/2019   90
ABB     83   50  30/12/2019   87
ABB     73   45  30/12/2019   87
.
.
.
.
ABB    100    67  29/06/2019  90
ABB     83    65  30/06/2019  81
infy   100    75  29/12/2019  90
infy    830  650  30/12/2019  810
infy    730  645  30/12/2019  788 
.
.
.
infy   1001  556  29/06/2019  904
infy    833  657  30/06/2019  812
infy    734  643  30/06/2019  735
我尝试过的

查询,但是在rank()处出错,无法与窗口函数一起使用。任何其他选择。

select * into SRTREND180 from (
select *
from (
    select 
        rank() over(partition by name order by high desc) rn_high180,
        rank() over(partition by name order by low asc) rn_low180,
        rank() over (partition by name order by high desc rows between 30 preceding and current row) rn_high30,
        rank() over (partition by name order by low asc rows between 30 preceding and current row) rn_low30,        
         t.*
    from Historic t
) Hist
where rn_high180 <= 5 or rn_low180 <= 5 or  rn_high30 <=5 or rn_low30 <=5
) SR

2 个答案:

答案 0 :(得分:0)

“在前30行和当前行之间行”是导致错误的窗口函数。尝试将过去30天的两个选择字段分开,放在一个单独的查询中,或者将它们放在子查询中,从选择的窗口部分移到where子句中选择数据。

编辑:在查询开始时尝试使用以下CTE(将表/字段名称更改为您的名称)。这样一来,您可以在拥有两个单独的数据表的同时编写查询,一个数据表在最近180天的排名低/高,另一个在最近30天的排名。

with last180 (name, closedate, low, high, lowrank, highrank) as
(
    select name, closedate, low, high, rank() over(partition by name order by low asc), rank() over(partition by name order by high desc)
    from @table where datediff(day, closedate, getdate()) <= 180
),
last30 (name, closedate, low, high, lowrank, highrank) as
(
    select name, closedate, low, high, rank() over(partition by name order by low asc), rank() over(partition by name order by high desc)
    from @table where datediff(day, closedate, getdate()) <= 30
)

答案 1 :(得分:0)

一种对无法对分区中的记录进行排序的解决方法是添加一个子查询以虚拟化存储桶,然后根据需要使用存储桶标记作为分区的一部分。

SQL Fiddle

MS SQL Server 2017架构设置

CREATE TABLE T (name NVARCHAR(20), High INT, Low INT, Date DATETIME, PrevClose INT)
INSERT T VALUES
('ABB', 100, 75,'12/29/2019',90),
('ABB', 83,  50,'12/30/2019',87),
('ABB', 73, 45,'12/30/2019',87),
('ABB', 100, 67,'06/29/2019',90),
('ABB', 83, 65,'06/30/2019',81),
('INFY', 100, 75,'12/29/2019',90),
('INFY', 830, 600,'12/30/2019',810),
('INFY', 730, 645,'12/30/2019',788),
('INFY', 1001, 556,'06/29/2019',904),
('INFY', 833, 657,'06/30/2019',812),
('INFY', 734,643, '06/30/2019',735),
('INFY', 734,643, '07/30/2019',735)

查询1

DECLARE @ReportDate DATETIME = GETDATE()

;WITH DataWithDayFlag AS
(
    select 
        *,
        DaysOut   =  DATEDIFF(DAY,date,@ReportDate),
        Bucket30  = CASE WHEN DATEDIFF(DAY,date,@ReportDate) <= 30 THEN 1 ELSE NULL END,
        Bucket180 = CASE WHEN DATEDIFF(DAY,date,@ReportDate) <= 180 THEN 1 ELSE NULL END

    FROM
        T
)
SELECT
  CASE WHEN Bucket180 IS NOT NULL THEN rank() over (partition by name, Bucket180 order by high desc) ELSE NULL END rn_high180,
  CASE WHEN Bucket180 IS NOT NULL THEN rank() over (partition by name, Bucket180 order by low asc) ELSE NULL END rn_low180,
  CASE WHEN Bucket30 IS NOT NULL THEN rank() over (partition by name, Bucket30 order by high desc) ELSE NULL END rn_high30,
  CASE WHEN Bucket30 IS NOT NULL THEN rank() over (partition by name, Bucket30 order by low asc) ELSE NULL END rn_low30,        
  t.*
from 
  DataWithDayFlag t
where  
  DaysOut <= 180
ORDER BY
    name

Results

| rn_high180 | rn_low180 | rn_high30 | rn_low30 | name | High | Low |                 Date | PrevClose | DaysOut | Bucket30 | Bucket180 |
|------------|-----------|-----------|----------|------|------|-----|----------------------|-----------|---------|----------|-----------|
|          3 |         1 |         3 |        1 |  ABB |   73 |  45 | 2019-12-30T00:00:00Z |        87 |       1 |        1 |         1 |
|          2 |         2 |         2 |        2 |  ABB |   83 |  50 | 2019-12-30T00:00:00Z |        87 |       1 |        1 |         1 |
|          1 |         3 |         1 |        3 |  ABB |  100 |  75 | 2019-12-29T00:00:00Z |        90 |       2 |        1 |         1 |
|          2 |         3 |    (null) |   (null) | INFY |  734 | 643 | 2019-07-30T00:00:00Z |       735 |     154 |   (null) |         1 |
|          4 |         1 |         3 |        1 | INFY |  100 |  75 | 2019-12-29T00:00:00Z |        90 |       2 |        1 |         1 |
|          1 |         2 |         1 |        2 | INFY |  830 | 600 | 2019-12-30T00:00:00Z |       810 |       1 |        1 |         1 |
|          3 |         4 |         2 |        3 | INFY |  730 | 645 | 2019-12-30T00:00:00Z |       788 |       1 |        1 |         1 |