SOLVED
All hail StackOverlow!
While I was gone, people left 2 solutions (thanks guys--what is the protocol for handing out karma for two wor
So you want:
C
to correspond to all rows in the group for a given day, so you can use MAX()
and MIN()
over the rows in that group.C2
to correspond to the last row in a given day.C3
to correspond to a row later than C2
on the same day. If none is found, i.e. C3.*
is NULL, then C2
is the latest on that day.This is often labeled a greatest-n-per-group
query, and it comes up frequently on Stack Overflow. Here's a solution that I tested for your test data, but you can follow the tag I added to your question for other solutions and discussion.
edit: I missed the requirement for both opening price and closing price. The following is edited.
SELECT DATE_FORMAT(C.`DTE`, '%m/%d/%Y') AS trading_day,
MIN(C.`PRICE`) AS min_price,
MAX(C.`PRICE`) AS max_price,
Copen.`PRICE` AS opening_price,
Cclose.`PRICE` AS closing_price
FROM `CHART_DATA` AS C
INNER JOIN `CHART_DATA` AS Cclose
ON DAY(C.`DTE`) = DAY(Cclose.`DTE`)
LEFT OUTER JOIN `CHART_DATA` AS Cclose_later
ON DAY(C.`DTE`) = DAY(Cclose_later.`DTE`) AND Cclose.`DTE` < Cclose_later.`DTE`
INNER JOIN `CHART_DATA` AS Copen
ON DAY(C.`DTE`) = DAY(Copen.`DTE`)
LEFT OUTER JOIN `CHART_DATA` AS Copen_earlier
ON DAY(C.`DTE`) = DAY(Copen_earlier.`DTE`) AND Copen.`DTE` < Copen_earlier.`DTE`
WHERE Cclose_later.`DTE` IS NULL AND Copen_earlier .`DTE` IS NULL
GROUP BY trading_day;
SELECT
a.trading_day, a.min_price, a.max_price,
b.price as opn_price,
c.price as cls_price
FROM
(SELECT
DATE_FORMAT(`DTE`, "%m/%d/%Y") AS trading_day,
MIN(`PRICE`) AS min_price,
MAX(`PRICE`) AS max_price,
MIN(`dte`) AS open_date,
MAX(`dte`) AS close_date
FROM `CHART_DATA`
GROUP BY trading_day) a
LEFT JOIN
`CHART_DATA` b ON b.dte = a.open_date
LEFT JOIN
`CHART_DATA` c ON c.dte = a.close_date
Note: this solution may present some problems if your opening or closing entry has the exact same date/time value as another row (i.e. the transaction that came immediately after opening, or immediately before closing). To address this, I would suggest that you add a sequence number that is stored in a way that guarantees uniqueness, and increasing-with-respect-to-time. If you do this, then you would use the sequence value in the place of dte
to replace the open_date
and close_date
I've used as join fields in my example.