решаемые
Всем привет StackOverlow!
Пока меня не было, люди оставили 2 решения (спасибо, ребята, каков протокол раздачи кармы за два рабочих решения?)
Вот решение, к которому я вернулся. он получен из ДРУГОГО решения StackOver:
Как получить первую и последнюю запись сгруппированной записи в запросе MySQL с помощью агрегатных функций?
... и моя адаптация:
SELECT
DATE_FORMAT(`DTE`, "%m/%d/%Y") AS trading_day,
MIN(`PRICE`) AS min_price,
MAX(`PRICE`) AS max_price,
SUBSTRING_INDEX(
GROUP_CONCAT(
PRICE
ORDER BY DTE ASC
)
, ',', 1 ) AS opn_price,
SUBSTRING_INDEX(
GROUP_CONCAT(
PRICE
ORDER BY DTE DESC
)
, ',', 1 ) AS cls_price
FROM `CHART_DATA`
GROUP BY trading_day
;
Данные, с которых начинается буква "Q", - это данные, которыми я пытаюсь закончить. Надеюсь, это поможет кому-то еще, так как я подозреваю, что мой журнал довольно распространен.
Я готов поспорить, что одно из этих трех решений имеет преимущество в производительности. Если кто-то знает внутреннюю работу MySQL и оптимизацию запросов и хочет порекомендовать «предпочтительное» решение, это будет полезно узнать в будущем.
КОНЕЦ РЕШЕН
ОБНОВЛЕНИЕ № 2
Пытаясь прийти к этому с другого направления, используя это:
http://forums.mysql.com/read.php?65,363723,363723
Я получаю:
SELECT
DATE_FORMAT(`DTE`, "%m/%d/%Y") AS trading_day,
MIN(`PRICE`) AS min_price,
MAX(`PRICE`) AS max_price,
(SELECT opn_price FROM
(SELECT
DATE_FORMAT(`DTE`, "%m/%d/%Y") AS a_day,
PRICE AS opn_price,
MIN(DTE) AS opn
FROM `CHART_DATA`
GROUP BY a_day
ORDER BY opn ASC LIMIT 1) AS tblO) AS opnqt,
(SELECT cls_price FROM
(SELECT
DATE_FORMAT(`DTE`, "%m/%d/%Y") AS a_day,
PRICE AS cls_price,
MIN(DTE) AS cls
FROM `CHART_DATA`
GROUP BY a_day
ORDER BY cls DESC LIMIT 1) AS tblC) AS clsqt
FROM `CHART_DATA` cht
GROUP BY trading_day;
Это страдает от такой же дисфункции, как запрос в первом обновлении ниже; возвращаемое значение clsqt (cls_price) является последней ценой закрытия, найденной в данных. Blech.
Кроме того, мы снова попадаем в «ужасно сложное» пространство запросов, и это НЕ МОЖЕТ быть хорошим для производительности.
Но если кто-нибудь увидит исправление для значения 'clsqt', я с радостью приму его и решу проблему производительности позже. :)
КОНЕЦ ОБНОВЛЕНИЯ # 2
UPDATE
Так близко ... вот где я сегодня:
SELECT
DATE_FORMAT(`cht1`.`DTE`, "%m/%d/%Y") AS trading_day,
MIN(`cht1`.`PRICE`) AS min_price,
MAX(`cht1`.`PRICE`) AS max_price,
MIN(cht1.DTE) AS opn_date1,
MIN(cht1.DTE) AS opn_date2,
`cht2`.`PRICE` AS opn_price,
MAX(cht1.DTE) AS cls_date1,
MAX(cht3.DTE) AS cls_date3,
`cht3`.`PRICE` AS cls_price
FROM `CHART_DATA` cht1
LEFT JOIN `CHART_DATA` cht2
ON cht2.DTE = cht1.DTE
LEFT JOIN `CHART_DATA` cht3
ON cht3.DTE = cht1.DTE
GROUP BY trading_day
HAVING opn_date1 = opn_date2
AND cls_date1 = cls_date3
;
Это корректно все перенастраивает, НО правильный 'cls_price' (он возвращает то же значение для 'cls_price', что и 'opn_price').
Однако 'cls_date1' и 'cls_date3' являются правильными значениями, поэтому я должен быть близко.
Кто-нибудь видит, кем я не являюсь?
КОНЕЦ ОБНОВЛЕНИЯ
Я занимался SO в связи с левыми и собственными соединениями ... и должен признать, что я не ворчу.
Я нашел этот «Q», который кажется очень близким к тому, что я хочу: левое соединение с условием для правой таблицы в mysql
Я пытаюсь получить дни открытия, закрытия, минимальной и максимальной цены из одной таблицы (пример данных ниже).
Мин и Макс легко:
SELECT
DATE_FORMAT(`DTE`, "%m/%d/%Y") AS trading_day,
MIN(`PRICE`) AS min_price,
MAX(`PRICE`) AS max_price
FROM `CHART_DATA`
GROUP BY trading_day;
Я хочу, чтобы результаты возвращались по дате, что-то вроде:
'trading_day' 'opn_price' 'min_price' 'max_price' 'cls_price'
Хорошо, так что я пробую "маленькие шаги" всего одним соединением ...
SELECT
DATE_FORMAT(`cht1`.`DTE`, "%m/%d/%Y") AS trading_day,
MIN(`cht1`.`PRICE`) AS min_price,
MAX(`cht1`.`PRICE`) AS max_price,
`cht2`.`PRICE` AS opn_price
FROM `CHART_DATA` cht1
LEFT JOIN `CHART_DATA` cht2
ON cht2.DTE = MIN(cht1.DTE)
GROUP BY trading_day;
... и я получаю сообщение «Неправильное использование групповой функции»
Конечно, удаление «GROUP BY» не поможет, так как мне нужно возвращать столбцы aggegate.
У меня есть действительно сложное решение, которое получает результаты открытия и закрытия, но не min и max - и они находятся в отдельных наборах результатов. У меня возникает ощущение, что я сделал это более сложным, чем необходимо, и что я мог бы просто понять, что происходит с самосоединениями, упомянутыми в «Q», указанном выше, что мое общее кодирование будет неизмеримо импровизировать. Но на прошедших выходных я потратил на это около 12 часов, и я чувствую себя еще более сбитым с толку.
На этом этапе приветствуются все знания, объяснения и наблюдения ...
/* SAMPLE TABLE AND DATA */
CREATE TABLE `CHART_DATA` (
`ID` varchar(10) DEFAULT NULL,
`DTE` datetime DEFAULT NULL,
`PRICE` double DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*Data for the table `CHART_DATA` */
INSERT INTO `chart_data`
(`id`,`dte`,`price`)
VALUES ('1','2011-01-01 00:10:00',0.65),
('2','2011-01-01 06:10:00',0.92),
('3','2011-01-01 12:10:00',0.59),
('4','2011-01-01 18:10:00',0.16),
('5','2011-01-02 00:10:00',0.28),
('6','2011-01-02 06:10:00',0.12),
('7','2011-01-02 12:10:00',0.92),
('8','2011-01-02 18:10:00',0.1),
('9','2011-01-03 00:10:00',0.34),
('10','2011-01-03 06:10:00',0.79),
('11','2011-01-03 12:10:00',1.23),
('12','2011-01-03 18:10:00',1.24),
('13','2011-01-04 00:10:00',1.12),
('14','2011-01-04 06:10:00',0.8),
('15','2011-01-04 12:10:00',0.65),
('16','2011-01-04 18:10:00',0.78),
('17','2011-01-05 00:10:00',0.65),
('18','2011-01-05 06:10:00',1.19),
('19','2011-01-05 12:10:00',0.89),
('20','2011-01-05 18:10:00',1.05),
('21','2011-01-06 00:10:00',0.29),
('22','2011-01-06 06:10:00',0.43),
('23','2011-01-06 12:10:00',0.26),
('24','2011-01-06 18:10:00',0.34),
('25','2011-01-07 00:10:00',0.22),
('26','2011-01-07 06:10:00',0.37),
('27','2011-01-07 12:10:00',1.22),
('28','2011-01-07 18:10:00',1.16),
('29','2011-01-08 00:10:00',0.3),
('30','2011-01-08 06:10:00',1.17),
('31','2011-01-08 12:10:00',0.62),
('32','2011-01-08 18:10:00',0.86),
('33','2011-01-09 00:10:00',0.84),
('34','2011-01-09 06:10:00',1.11),
('35','2011-01-09 12:10:00',0.92),
('36','2011-01-09 18:10:00',1.03),
('37','2011-01-10 00:10:00',1.13),
('38','2011-01-10 06:10:00',0.58),
('39','2011-01-10 12:10:00',1.03),
('40','2011-01-10 18:10:00',0.21),
('41','2011-01-11 00:10:00',0.12),
('42','2011-01-11 06:10:00',1.01),
('43','2011-01-11 12:10:00',0.19),
('44','2011-01-11 18:10:00',1.14),
('45','2011-01-12 00:10:00',0.55),
('46','2011-01-12 06:10:00',0.75),
('47','2011-01-12 12:10:00',0.66),
('48','2011-01-12 18:10:00',1.1),
('49','2011-01-13 00:10:00',0.68),
('50','2011-01-13 06:10:00',0.3),
('51','2011-01-13 12:10:00',0.9),
('52','2011-01-13 18:10:00',0.88),
('53','2011-01-14 00:10:00',0.64),
('54','2011-01-14 06:10:00',1.06),
('55','2011-01-14 12:10:00',1.12),
('56','2011-01-14 18:10:00',0.76),
('57','2011-01-15 00:10:00',0.18),
('58','2011-01-15 06:10:00',1.08),
('59','2011-01-15 12:10:00',0.66),
('60','2011-01-15 18:10:00',0.38),
('61','2011-01-16 00:10:00',1),
('62','2011-01-16 06:10:00',1.18),
('63','2011-01-16 12:10:00',1.15),
('64','2011-01-16 18:10:00',0.58),
('65','2011-01-17 00:10:00',1.04),
('66','2011-01-17 06:10:00',0.81),
('67','2011-01-17 12:10:00',0.35),
('68','2011-01-17 18:10:00',0.91),
('69','2011-01-18 00:10:00',0.14),
('70','2011-01-18 06:10:00',0.13),
('71','2011-01-18 12:10:00',1.03),
('72','2011-01-18 18:10:00',0.16),
('73','2011-01-19 00:10:00',1.05),
('74','2011-01-19 06:10:00',1.13),
('75','2011-01-19 12:10:00',1.21),
('76','2011-01-19 18:10:00',0.34),
('77','2011-01-20 00:10:00',0.63),
('78','2011-01-20 06:10:00',0.62),
('79','2011-01-20 12:10:00',0.19),
('80','2011-01-20 18:10:00',1.21),
('81','2011-01-21 00:10:00',0.83),
('82','2011-01-21 06:10:00',0.99),
('83','2011-01-21 12:10:00',0.83),
('84','2011-01-21 18:10:00',0.21),
('85','2011-01-22 00:10:00',0.8),
('86','2011-01-22 06:10:00',0.69),
('87','2011-01-22 12:10:00',0.87);