Reputation: 1469
I have a table of stock
data (the db is MySQL):
trade_time price
2013-01-02 09:43:00 515.61
2013-01-03 09:39:00 525.90
2013-01-03 11:38:00 539.44
2013-01-03 13:22:00 509.16
2013-01-04 09:47:00 507.40
2013-01-04 14:33:00 517.45
2013-01-07 09:33:00 550.42
2013-01-07 13:13:00 524.85
2013-01-07 14:51:00 536.44
I would like to return the last traded price for each day
trade_date price
2013-01-02 515.61
2013-01-03 509.16
2013-01-04 517.45
2013-01-07 536.44
What makes this question different from other "selecting the latest record based on datetime" questions on this site is that input is in datetime
but output is in date
. Let me know this question has already been answered.
Upvotes: 5
Views: 14312
Reputation: 39
Try with DATEDIFF instead.
SELECT trade_time, price
FROM
(Select DATEDIFF(DAY,LEAD(tradetime) OVER(ORDER BY tradetime desc),LAG(tradetime) OVER(ORDER BY tradetime desc) ) diff, price from yourTable )subquery
Where diff=1
Upvotes: 0
Reputation: 7571
I understand this is an implementation in MY-SQL, but I tried in SQL-Server just for fun and this query gives the requisite output:
SELECT CAST(SQ.TT AS DATE) AS TRADED_DATE, PRICE
FROM STOCK
INNER JOIN
(SELECT MAX(TRADE_TIME) AS TT
FROM STOCK
GROUP BY CAST(TRADE_TIME AS DATE)) SQ
ON SQ.TT = TRADE_TIME
Output as
TRADED_DATE PRICE
----------- ---------------------------------------
2013-01-02 515.61
2013-01-03 509.16
2013-01-04 517.45
2013-01-07 536.44
(4 rows affected)
Upvotes: 1
Reputation: 544
Here is an efficient solution using window function ROW_NUMBER() over a type cast of the timestamp column to date:
select trade_date, price
from (
select trade_date, price, row_number() over
(partition by date(trade_date)
order by trade_date desc) as row_num
from stock) as subquery
where row_num = 1
order by trade_date
Upvotes: 1
Reputation: 520908
You may join to a subquery which finds the maximum datetime for each date.
SELECT t1.trade_time, t1.price
FROM yourTable t1
INNER JOIN
(
SELECT DATE(trade_time) AS trade_date, MAX(trade_time) AS max_trade_time
FROM yourTable
GROUP BY DATE(trade_time)
) t2
ON t2.trade_date = DATE(t1.trade_time) AND
t2.max_trade_time = t1.trade_time
ORDER BY
t1.trade_time;
Upvotes: 6
Reputation: 1269493
You can use a correlated subquery:
select t.*
from t
where t.trade_date = (select max(t2.trade_date)
from t t2
where date(t2.trade_date) = date(t.trade_date)
);
Upvotes: 0