[英]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.对不处理分区中的记录进行排名的一种解决方法是添加一个子查询来虚拟化存储桶,然后根据需要使用存储桶标记作为分区的一部分。
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
| 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.