Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment utiliser Group By et self-join pour renvoyer l'ensemble de résultats de prix quotidien min, max, open et close ?

Alors vous voulez :

  • L'alias C pour correspondre à toutes les lignes du groupe pour un jour donné, vous pouvez donc utiliser MAX() et MIN() sur les lignes de ce groupe.
  • L'alias C2 pour correspondre à la dernière ligne d'un jour donné.
  • L'alias C3 pour correspondre à une ligne postérieure à C2 le même jour. Si aucun n'est trouvé, c'est-à-dire C3.* est NULL, alors C2 est le dernier de ce jour.

Ceci est souvent étiqueté comme un greatest-n-per-group requête, et elle revient fréquemment sur Stack Overflow. Voici une solution que j'ai testée pour vos données de test, mais vous pouvez suivre la balise que j'ai ajoutée à votre question pour d'autres solutions et discussions.

modifier : J'ai raté l'exigence du prix d'ouverture et du prix de clôture. Ce qui suit est modifié.

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;