2010-08-16 8 views
1

У меня есть Ticker, Dt, [Open], Volume для ввода таблицыSQL макс предыдущих строк

Dt is yyyy-mm-dd 

Я хочу вернуть каждую строку где тикер = 'IBM', а также возвращающий Ticker, Dt, [Открыть], Поля тома, а затем включить столбец максимум, чтобы говорить только за предыдущие x дней. Скажем, 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, но очевидно не группа значение Макс правильно.

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' 

Спасибо! Adam

+1

Для каких СУБД? Выглядит SQL Servery, но какая версия? Также 3 торговых дня или 3 календарных дня? –

+0

MS SQL Server 2008R2. 3 календарных дня. – user422224

+0

Я думаю, что был неправ, я ищу рыночные дни, а не календарные дни:>) – user422224

ответ

2

Вы имеете в виду это?

отредактированные отрабатывать последние 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

+1. Легко с CTE при работе с этими днями/пробелами при необходимости в предыдущие * n * дни. –

0

Я думаю, я просто ответил на мой собственный вопрос:

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' 
0

Похоже, что вы хотели ваш 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 
+0

Спасибо p.campbell, я считаю, что мы оба пришли к такому же ответу, у меня была последняя дата только для уменьшения объема данных. Это в точности то, что я ищу! – user422224

+0

Я думаю, что был неправильным, я ищу рыночные дни, а не календарные дни:>) – user422224

+0

@user - См. Мое редактирование. –