【问题标题】:SQL max for previous rows前行的 SQL 最大值
【发布时间】:2011-03-30 16:35:43
【问题描述】:

我有输入表的 Ticker、Dt、[Open]、Volume

Dt is yyyy-mm-dd

我想返回 ticker = 'IBM' 的每一行,还返回 Ticker、Dt、[Open]、Volume 字段,然后包含一个仅表示前 x 天的 max 列。为了不发布太多数据,假设 3 天。

但我不知道如何使时间范围正确,以便最大值只包含在这么多天之前。

在表中:

Tck    Dt          [Open]      Volume   
IBM 2010-05-21  122.160000  6881000
IBM 2010-05-24  125.260000  6876000
IBM 2010-05-25  121.470000  9498800
IBM 2010-05-26  124.890000  9085900
IBM 2010-05-27  125.050000  7726500

我需要什么:

Tck    Dt          [Open]      Volume  Max
IBM 2010-05-21  122.160000  6881000 122.160000
IBM 2010-05-24  125.260000  6876000 125.260000
IBM 2010-05-25  121.470000  9498800 125.260000
IBM 2010-05-26  124.890000  9085900 125.260000
IBM 2010-05-27  125.050000  7726500 125.050000

这是我当前的 SQL,但显然没有正确分组 Max 值。

Select Ticker, 
       Dt, 
       [Open], 
       Volume,
       (Select Max([Open]) from Daily_NYSE
            where Ticker = 'IBM'
            and Dt between DateAdd(Day,-3,'2010-05-27') and '2010-05-27') as 'Max'
from Daily_NYSE
where Ticker = 'IBM'
and Dt between DateAdd(Day,-6,'2010-05-27') and '2010-05-27' 

谢谢! 亚当

【问题讨论】:

  • 对于什么 RDBMS?看起来 SQL Servery 但什么版本?还有 3 个交易日还是 3 个日历日?
  • MS SQL Server 2008R2。 3 个日历日。
  • 我想我错了,我在寻找市场日,而不是日历日 :>)

标签: sql sql-server tsql sql-server-2008-r2


【解决方案1】:

你的意思是这样吗?

最后 3 个交易日已修改

SELECT * INTO #stocks FROM 
(
SELECT 'IBM' AS Ticker, CAST('2010-05-21' AS DATE) AS dt, 122.160000 AS [OPEN] ,12639500 AS Volume UNION ALL
SELECT 'IBM' AS Ticker, CAST('2010-05-24' AS DATE), 125.260000 AS [OPEN] ,6876000 AS Volume UNION ALL
SELECT 'IBM' AS Ticker, CAST('2010-05-25' AS DATE), 121.470000 AS [OPEN] ,9498800 AS Volume UNION ALL
SELECT 'IBM' AS Ticker, CAST('2010-05-26' AS DATE), 124.890000 AS [OPEN] ,9085900 AS Volume UNION ALL
SELECT 'IBM' AS Ticker, CAST('2010-05-27' AS DATE), 125.050000 AS [OPEN] ,7726500 AS Volume 
) X

;WITH NumberedStocks AS
(
SELECT Ticker, dt, [Open], Volume, 
     ROW_NUMBER() OVER (PARTITION BY Ticker ORDER BY dt) AS rn
FROM #stocks
)
SELECT ns1.Ticker, ns1.dt, ns1.[Open], ns1.Volume, MAX(ns2.[Open]) AS MaxPrev3
FROM NumberedStocks ns1 LEFT JOIN NumberedStocks ns2
ON ns1.Ticker = ns2.Ticker AND ns2.rn 
   BETWEEN ns1.rn-3 AND ns1.rn-1 /*Or should this be ns1.rn-2 AND ns1.rn?*/
GROUP BY ns1.Ticker, ns1.dt, ns1.[Open], ns1.Volume

【讨论】:

  • +1。在需要前 n 天的情况下处理那些日子/间隙时,使用 CTE 很容易。
【解决方案2】:

我想我只是回答了我自己的问题:

Select a.Ticker, 
       a.Dt, 
       a.[Open], 
       a.Volume,
       (Select Max([Open]) from Daily_NYSE b
            where Ticker = 'IBM'
            and b.Dt between DateAdd(Day,-2,a.Dt) and a.Dt) as 'Max'
from Daily_NYSE a
where Ticker = 'IBM'
and a.Dt between DateAdd(Day,-12,'2010-05-27') and '2010-05-27' 

【讨论】:

    【解决方案3】:

    您似乎希望您的 Max 与指定日期的前 3 天相关? 如果没有,请评论。

    DECLARE @SomeDate smalldatetime    
    SELECT @SomeDate = '2010-05-27'
    
    SELECT Ticker, 
           Dt, 
           [Open], 
           Volume,
           (SELECT Max([Open]) 
                FROM Daily_NYSE AS D2
                WHERE D2.Ticker  = 'IBM'
                AND D2.Dt BETWEEN DateAdd(Day,-3,D1.Dt) AND D1.Dt
            ) AS 'Max'
    FROM    Daily_NYSE AS D1
    WHERE   Ticker = 'IBM'
    AND     Dt BETWEEN DateAdd(Day,-6,@SomeDate) AND @SomeDate
    

    【讨论】:

    • 谢谢p.campbell,我相信我们都想出了相同的答案,我最后一次约会只是为了减少数据量。这正是我想要的!
    • 我想我错了,我在寻找市场日,而不是日历日 :>)
    猜你喜欢
    • 2020-05-14
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多