3

I have this SELECT:

SELECT
  DATE_FORMAT(`created`, '%Y-%m') as byMonth,
  COUNT(*) AS Total 
FROM 
  `qualitaet`
WHERE
  `created` >= MAKEDATE(year(now()-interval 1 year),1) + interval 5 month
AND
  `status`=1
GROUP BY 
  YEAR(`created`), MONTH(`created`)
ORDER BY 
  YEAR(`created`) ASC

and get this result:

| byMonth | Total |
| 2015-06 |   2   |
| 2015-09 |  12   |
| 2015-10 |   3   |
| 2015-12 |   8   |
| 2016-01 |   1   |

see SQL-Fiddle here

The WHERE clause is important because i need it as current fiscal year starting on June, 1 in my example.

As you can see, i have no records for Jul, Aug and Nov. But i need this records with zero in Total.

So my result should look like this:

| byMonth | Total |
| 2015-06 |   2   |
| 2015-07 |   0   |
| 2015-08 |   0   |
| 2015-09 |  12   |
| 2015-10 |   3   |
| 2015-11 |   0   |
| 2015-12 |   8   |
| 2016-01 |   1   |

is there a way to get this result?

4

1 回答 1

2

您需要生成所有想要的日期,然后将您的数据加入日期。另请注意,将一些谓词放在左连接的ON子句中,将其他谓词放在子句中是很重要的WHERE

SELECT
  CONCAT(y, '-', LPAD(m, 2, '0')) as byMonth,
  COUNT(`created`) AS Total 
FROM (
  SELECT year(now())     AS y UNION ALL
  SELECT year(now()) - 1 AS y 
) `years`
CROSS JOIN (
  SELECT  1 AS m UNION ALL
  SELECT  2 AS m UNION ALL
  SELECT  3 AS m UNION ALL
  SELECT  4 AS m UNION ALL
  SELECT  5 AS m UNION ALL
  SELECT  6 AS m UNION ALL
  SELECT  7 AS m UNION ALL
  SELECT  8 AS m UNION ALL
  SELECT  9 AS m UNION ALL
  SELECT 10 AS m UNION ALL
  SELECT 11 AS m UNION ALL
  SELECT 12 AS m
) `months`
LEFT JOIN `qualitaet` q
ON YEAR(`created`) = y 
  AND MONTH(`created`) = m
  AND `status` = 1
WHERE STR_TO_DATE(CONCAT(y, '-', m, '-01'), '%Y-%m-%d') 
    >= MAKEDATE(year(now()-interval 1 year),1) + interval 5 month
  AND STR_TO_DATE(CONCAT(y, '-', m, '-01'), '%Y-%m-%d') 
    <= now()
GROUP BY y, m
ORDER BY y, m

以上是如何工作的?

  • CROSS JOIN在所有可用年份和所有可用月份之间创建笛卡尔积。这就是你想要的,你想要所有没有间隔的年月组合。
  • LEFT JOIN将所有qualitaet记录添加到结果中(如果存在)并将它们加入到之前的年月笛卡尔积中。在这里放置谓词之类的谓词很重要status = 1
  • COUNT(created)只计算 的非 NULL 值created,即当LEFT JOIN为任何给定的年月不产生任何行时,我们想要0结果,而不是1,即我们不想计算该NULL值。

性能说明

ON以上在您的和WHERE谓词中大量使用了字符串操作和日期时间算术。这不适用于大量数据。在这种情况下,您应该更好地在表中预先截断和索引您的qualitaet年月,并仅对这些值进行操作。

于 2016-01-01T15:58:13.297 回答