I need to list the trade dates, and stock closing prices for the each month of the year (which I will refer to as the 'current' month) and the stock closing price for the month preceding the 'current' month.
The StockData
table I am using has has columns for date, Stock high, low, opening, closing, and volume for each trade date and ticker symbol.
Initially, I used AVG
:
SELECT
YEAR(TradeDate) AS Year,
MONTH(TradeDate) AS Month,
TickerSymbol,
AVG(ST_Close) AS CurrentClose,
LAG (AVG(ST_Close), 1, 0) OVER (ORDER BY TickerSymbol, YEAR(TradeDate), MONTH(TradeDate), TickerSymbol) AS PreviousMonthClose,
FROM
StockData
WHERE
TradeDate >= '2000-01-01' AND ST_Close IS NOT NULL
GROUP BY
YEAR(TradeDate), MONTH(TradeDate), TickerSymbol
ORDER BY
YEAR(TradeDate), MONTH(TradeDate), TickerSymbol;
But instead of using the average, I'd like to pull the stock closing price from the last day of each month, and the previous last day of the last month (for April 2010, I want to show the Stock Closing price on April 30th, 2010 and March 31st, 2010)
Any ideas on how to do this?
You can use window functions and conditional aggregation:
SELECT sd.*
FROM (SELECT sd.*,
ROW_NUMBER() OVER (PARTITION BY TickerSymbol, YEAR(TradeDate), MONTH(TradeDate)
ORDER BY TradeDate DESC) as seqnum
FROM StockData sd
WHERE TradeDate >= '2000-01-01' AND ST_Close IS NOT NULL
) sd
WHERE seqnum = 1
ORDER BY TradeDate, TickerSymbol;
This gets all the information from the last record for each month.
ORDER BY YEAR(TradeDate), MONTH(TradeDate), TickerSymbol;
Below is one method, which assumes the previous close value you need is from the date the stock last traded during the previous month.
WITH
daily_close AS (
SELECT
TradeDate
, TickerSymbol
, ST_Close
, ROW_NUMBER() OVER(PARTITION BY TickerSymbol, EOMONTH(TradeDate) ORDER BY TradeDate DESC) AS day_num
FROM dbo.StockData
WHERE TradeDate >= '2012-01-01'
AND ST_Close IS NOT NULL
)
SELECT
YEAR(curr.TradeDate) AS Year
, MONTH(curr.TradeDate) AS Month
, curr.TickerSymbol
, curr.ST_Close AS CurrentMonthClose
, prev.ST_Close AS PriorMonthClose
FROM daily_close AS curr
LEFT JOIN daily_close AS prev ON
prev.TickerSymbol = curr.TickerSymbol
AND prev.TradeDate < DATEADD(month, -1, DATEADD(day, 1, curr.TradeDate))
AND prev.TradeDate >= DATEADD(month, -2, DATEADD(day, 1, curr.TradeDate))
AND prev.day_num = 1
WHERE
curr.day_num = 1
ORDER BY
Year
, Month
, TickerSymbol;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.