Использование результатов родительских запросов во вложенном выборе
-
06-09-2019 - |
Вопрос
Я уверен, что это довольно тривиальная проблема, но я не уверен, что нужно поискать в Google, чтобы найти решение.
У меня есть таблица, которая выглядит следующим образом:
CREATE TABLE IF NOT EXISTS `transactions` (
`name` text collate utf8_swedish_ci NOT NULL,
`value` decimal(65,2) NOT NULL,
`date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci ROW_FORMAT=COMPACT;
Я заполняю это, вырезая и вставляя данные из моей службы интернет-банкинга.Значение может быть отрицательным или положительным значением, то, что содержат дата и имя, должно быть достаточно очевидным ;) Я создал запрос, позволяющий мне видеть итоговую строку за каждый месяц:
SELECT sum(`value`) as 'change', DATE_FORMAT(`date`, '%M %Y') as 'month'
FROM `transactions`
WHERE 1
GROUP BY year(`date`), month(`date`)
Теперь я хотел бы добавить общую сумму накопленных денег на счете в конце месяца в качестве дополнительного столбца.
SELECT sum(`value`) as 'change', DATE_FORMAT(`date`, '%M %Y') as 'month',
(SELECT sum(`value`) FROM `transactions` WHERE `date` <= 123) as 'accumulated'
FROM `transactions`
WHERE 1
GROUP BY year(`date`), month(`date`)
123 - это не совсем то, что я там хочу, но я не понимаю, как получить результат из моего DATE_FORMAT внутри этого подзапроса.
Является ли это вообще правильным подходом к решению проблемы?
В основном это личное упражнение (выполняется на очень маленьком наборе данных), поэтому я не очень беспокоюсь о производительности, читаемый SQL гораздо важнее.
Я запускаю таблицу InnoDB в MySQL 5.0.45
Решение
SELECT change,
CONCAT(mymonth, ' ', myyear) AS 'month',
(
SELECT SUM(`value`)
FROM `transactions`
WHERE `date` < DATE_ADD(STR_TO_DATE(CONCAT('01.', mymonth, '.', myyear, '%D.%M.%Y'), INTERVAL 1 MONTH))
)
FROM (
SELECT sum(`value`) as 'change', YEAR(date) AS myyear, MONTH(date) AS mymonth
FROM `transactions`
WHERE 1
GROUP BY
YEAR(`date`), MONTH(`date`)
) q
Вы написали, что вы не следите за производительностью, но этот синтаксис не намного сложнее, но будет более эффективным (на всякий случай):
SELECT SUM(value) AS change,
CONCAT(MONTH(`date`), ' ', YEAR(`date`)) AS 'month',
@r : = @r + SUM(value) AS cumulative
FROM (
SELECT @r := 0
) AS vars,
transactions
WHERE 1
GROUP BY
YEAR(`date`), MONTH(`date`)
ORDER BY
YEAR(`date`), MONTH(`date`)
Этот будет учитываться кумулятивно SUM
это тоже, но каждый месяц это будет учитываться только один раз.