简体   繁体   English

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

[英]selecting Top 5 max highs and 5 min Low for specific period say past 180 and 30 days in same query

Following is the table data, need to find out the top 5 max high and min low for the entire 180 days and the same for the last 30 days in the same query.以下是表数据,需要在同一查询中找出整个 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

Query, which I tried, but getting an error at rank() cannot be used with window functions.查询,我尝试过,但在 rank() 出现错误不能与窗口函数一起使用。 any alternatives.任何替代方案。

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

"rows between 30 preceding and current row" is the window function that is causing the error. “前 30 行和当前行之间的行”是导致错误的窗口函数。 Try separating out the two select fields for the last 30 days into a separate query, or put them in a sub-query selecting off of the data with the windowed part of the select moved to the where clause.尝试将过去 30 天的两个选择字段分离到一个单独的查询中,或者将它们放在一个子查询中,从数据中选择数据,并将选择的窗口部分移至 where 子句。

EDIT: Try using the following CTEs at the start of the query (change the table/field names to yours).编辑:尝试在查询开始时使用以下 CTE(将表/字段名称更改为您的)。 This will allow you to write a query while having two separate data tables, one with the ranked lows/highs for the last 180 days, and one for the last 30 days.这将允许您在拥有两个单独的数据表的情况下编写查询,一个具有过去 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
)

One workaround to rank not working on records in partition is to add a subquery to virtualize the buckets and then use the bucket marker as part of the partition as needed.对不处理分区中的记录进行排名的一种解决方法是添加一个子查询来虚拟化存储桶,然后根据需要使用存储桶标记作为分区的一部分。

SQL Fiddle SQL小提琴

MS SQL Server 2017 Schema Setup : 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)

Query 1 :查询 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 |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过一次有效查询选择过去30天和过去7天注册的用户 - Selecting Users signed up in past 30 days and in past 7 days in one efficient query 选择特定时间段的烛台数据(最大,最小,打开,关闭) - Selecting Candlestick data (max, min, open, close) for specific period of time 在“高”列中选择前 5 条最大记录,并从“低”列中的“低”列中选择前 5 条记录,并从按股票名称分区的同一表中选择 - select top 5 max records in "High" column and 5 min records from "Low" Column in same query and from same table partitioned by stock name 在单个查询中从 SQL 中的同一列中选择最大值和最小值 - Selecting a Max and Min from the same column in SQL in a single query 用于为每个唯一 ID 选择最大日期和前 30 天之间的数据点的 Hive 查询 - Hive query for selecting data points in between max date and previous 30 days for each unique id 在时间段内选择星期几 - Selecting specific days of week within time period 查询以获取过去30天不同列的记录 - Query to get records for the past 30 days for different columns 获取过去 30 天内每天的查询结果 - Getting the results of a query for each day in the past 30 days sql查询以计算同一列中最晚和最晚日期之间的总天数 - sql query to count total days between min and max date from same column 查询以返回特定日期后的+-30天 - Query to return +- 30 days from a specific date
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM