0

私はこのクエリを持っています

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(`acceptDate`, '%Y%M') AS timeUnit
FROM `agreements` 
    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

出力:

userId  timeUnit    sum count   avg
4         201001    6000    1   6000.0000
4         201003    12000   2   6000.0000
4         201004    19500   3   6500.0000

しかし、ご覧のとおり、いくつかの日付の間にギャップがあり、出力を連続した範囲にする必要があります。

userId  timeUnit    sum count   avg
4         201001    6000    1   6000.0000
4         201002    0       2   3000.0000
4         201003    12000   3   6000.0000
4         201004    19500   4   4875.0000

このクエリ

(SELECT DATE_FORMAT(`acceptDate`, '%Y%M') AS timeUnit FROM `agreements` GROUP BY timeUnit )

完全な日付範囲を出力しますが、2 つのクエリを LEFT JOIN しようとすると、カウントと平均がすべて台無しになります。探している結果を取得するにはどうすればよいですか?

4

1 に答える 1

1

2012 年 2 月の契約表にエントリがないと仮定すると、単純な日付を含む表を作成することは常に適切です。

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();

必要に応じて日付範囲を調整します。

次に、次のようにクエリを記述できます。変数やサブクエリは必要ないことがわかったので、少し単純化しました。

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

アップデート:

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
于 2012-11-26T10:50:30.257 に答える