запрос mysql использует каждую строку другого запроса

Я много искал, но не нашел полезного ответа:

я хочу иметь список итогов за период, который определяет пользователь, указав дату начала и окончания. Итоги должны каждый раз быть от даты начала до начала с даты начала и добавлять каждую строку 1 день. поэтому последняя строка дает итоги от даты начала до даты окончания. пример: - заданный период = начало 01.01.2013 , конец = 31.01.2013

total day 1 = 100
total day 2 = 0 (not listed in my totalsperday query, but should have a row in my final query)
total day 3 = 140
total day 4 = 20
...

final table should look like:
end day 1: 100
end day 2: 100
end day 3: 240
end day 4: 260
...

поэтому у меня есть запрос, который вычисляет все дни:

SELECT '2013-01-01' as startdate, w.endDate
FROM
(
    SELECT date('2013-01-01' + INTERVAL u.i*100 + v.i*10 + w.i DAY) AS endDate
    FROM sysints AS u
    JOIN sysints AS v
    JOIN sysints AS w
    WHERE ( u.i*100 + v.i*10 + w.i ) <= 
    (
        SELECT DATEDIFF( '2013-01-31','2013-01-01') as ddff
    )
) w
ORDER BY w.endDate ASC

и у меня есть запрос, который вычисляет итоги в день

SELECT p.selldate, SUM(p.price) as totalPerDay
FROM products p
WHERE   '2013-01-01' >= p.selldate <= '2013-01-31'
GROUP BY p.selldate
ORDER BY p.selldate ASC

теперь трудно объединить эти два, чтобы получить мой окончательный результат.

в основном, как должен выглядеть окончательный запрос:

- make the sum of sumperday from day 1 to day 1
- make the sum of sumperday from day 1 to day 2
- make the sum of sumperday from day 1 to day 3 
...

любая помощь? Спасибо. это упрощенный пример моего последнего запроса.


person kvl    schedule 04.02.2013    source источник
comment
какую версию mysql вы используете? один из вариантов - установить хранимую процедуру и использовать курсоры - я могу создать образец для вас   -  person Anda Iancu    schedule 04.02.2013
comment
Я думаю, что это можно сделать, но, чтобы быть точным, мне нужны описания таблицы, чтобы что-то делать. Если возможно, дайте описание таблиц   -  person Vineet1982    schedule 04.02.2013


Ответы (1)


Ниже приведен образец. Идея состоит в том, чтобы получить исходный набор данных, упорядоченный по дате и имеющий сводные итоги, неявные записи диапазона дат. Затем, используя курсор, вы можете пройти через каждую строку, чтобы получить окончательный итоговый столбец (столбец amountCalc в образце), просто суммируя предыдущие записи - это сработает, потому что у вас уже есть столбцы, упорядоченные по дате.

Процедура может иметь и другие входные/выходные параметры. Вместо того, чтобы получать информацию из таблицы, вы можете получить данные из одного представления, где представление может быть уже упорядочено по дате по возрастанию. Это всего лишь образец, поэтому его можно настроить по мере необходимости.

Удачи.

-- drop table `Balance`;
CREATE TABLE `Balance` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date` DATE NOT NULL,
  `account` varchar(30) NOT NULL,
  `amount` DECIMAL(10,2) NOT NULL, 
  PRIMARY KEY (`id`)
);

INSERT INTO `Balance` (`date`, `account`, `amount`) VALUES 
('2013-01-02', 'T355176', 8700), 
('2013-01-03', 'T355176', 8900), 
('2013-01-04', 'T355215', 33308), 
('2013-01-03', 'T355215', 116581), 
('2013-01-06', 'T812022', 275000), 
('2013-01-02', 'T812063', 136500), 
('2013-01-05', 'T812063', 11682), 
('2013-01-06', 'T812064', 615100), 
('2013-01-03', 'T812064', 25000), 
('2013-01-02', 'T812085', 82500);


SELECT * FROM Balance WHERE date >= '2013-01-01' AND date <= '2013-01-06' ORDER BY date ASC;
CALL sp_getTotals('2013-01-01', '2013-01-06');


-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`%` PROCEDURE `sp_getTotals`(IN startDate DATE, IN endDate DATE)
BEGIN


DECLARE dt DATE;
DECLARE amt DECIMAL(10,2);
DECLARE amtCalcPart DECIMAL(10,2);
DECLARE done INT DEFAULT 0;

DECLARE dtStart DATE;
DECLARE dtEnd DATE;

DECLARE cur1 CURSOR FOR SELECT date, amount FROM `TempMB`;
DECLARE cur2 CURSOR FOR SELECT startDate, endDate;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;


DROP TEMPORARY TABLE IF EXISTS `TempMB`;
CREATE TEMPORARY TABLE IF NOT EXISTS `TempMB` (
`id` int(11) NOT NULL AUTO_INCREMENT,
  `date` DATE NOT NULL,
  `amount` DECIMAL(10,2) NULL DEFAULT 0.00,
  `amountCalc` DECIMAL(10,2) NULL DEFAULT 0.00,
  PRIMARY KEY (`id`)
);


SET dtStart = DATE(startDate);
SET dtEnd = DATE(endDate);

WHILE dtStart <= dtEnd DO
    INSERT INTO `TempMB` (`date`) SELECT dtStart;
    SET dtStart = DATE_ADD(dtStart, INTERVAL 1 DAY);
END WHILE;


SELECT * FROM TempMB;

-- Fill temp table with info needed
UPDATE `TempMB` t 
INNER JOIN 
(
    SELECT date, SUM(amount) AS amount
    FROM Balance 
    WHERE 
        date >= startDate AND date <= endDate 
    GROUP BY date
    ORDER BY date ASC
) b ON b.date = t.date 
SET 
    t.amount = b.amount;
/*INSERT INTO `TempMB` (`date`, `amount`)
SELECT date, SUM(amount) AS amount
FROM Balance 
WHERE 
    date >= startDate AND date <= endDate 
GROUP BY date
ORDER BY date ASC;
*/


SET amtCalcPart = 0.00;
-- Initialise cursor
OPEN cur1;
-- USE BEGIN-END handler for cursor-control within own BEGIN-END block
BEGIN
DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;
-- Loop cursor throu temp records
LOOP 
    -- Get next value
    FETCH cur1 INTO dt, amt;

    -- Calculate amountCalc
    SET amtCalcPart = (SELECT SUM(amount) as amt FROM `TempMB` WHERE Date <= dt);
    UPDATE `TempMB` SET amountCalc = amtCalcPart WHERE date = dt;

END LOOP;
END;

-- Release cursor
CLOSE cur1;

SELECT * FROM TempMB;

END
person Anda Iancu    schedule 04.02.2013