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

Comment LEFT JOIN, pour créer une plage de dates ?

En supposant qu'il vous manque une entrée dans votre tableau des accords pour 2012-02, il est toujours bon d'avoir un tableau contenant simplement des dates.

CREATE TABLE dates(`date` date primary key);

DROP PROCEDURE IF EXISTS insertDates;
DELIMITER $$
CREATE PROCEDURE insertDates()
BEGIN
SET @start_date = '2010-01-01';
WHILE (@start_date <= '2010-12-31') DO
INSERT INTO dates VALUES (@start_date);
SET @start_date:=DATE_ADD(@start_date, INTERVAL 1 DAY);
END WHILE;
END $$
DELIMITER ;

CALL insertDates();

Ajustez la plage de dates en fonction de vos besoins.

Ensuite, vous pouvez écrire votre requête comme suit. Je l'ai un peu simplifié, car je n'ai vu aucun besoin de vos variables ou de la sous-requête.

SELECT userId, DATE_FORMAT(dates.`date`, '%Y%M') AS timeUnit, 
  SUM(orderValue), 
  COUNT(orderValue),
  AVG(orderValue)
FROM 
dates LEFT JOIN
`agreements` ON dates.date = agreements.acceptDate
  WHERE userId = 4 
  AND acceptDate > '2000-00-00'
GROUP BY userId, timeUnit

MISE À JOUR :

SELECT userId, orgQuery.timeUnit, 
  @SUM := @SUM + orgQuery.orderValue AS sum, 
  @COUNT := @COUNT + 1 AS count, 
  @AVG := @SUM / @COUNT AS avg
    FROM (
    SELECT userid, orderValue,  
      DATE_FORMAT(dates.`date`, '%Y%M') AS timeUnit
FROM dates LEFT JOIN
`agreements` ON dates.date = agreements.acceptDate
    WHERE userId = 4 
    AND acceptDate > '2000-00-00' 
   GROUP BY timeUnit
)
AS orgQuery, 
  (SELECT @COUNT := 0, @SUM := 0,@AVG :=0) 
 AS extra GROUP BY timeUnit