1. <legend id='Sf0qb'><style id='Sf0qb'><dir id='Sf0qb'><q id='Sf0qb'></q></dir></style></legend>

      <tfoot id='Sf0qb'></tfoot>
      1. <small id='Sf0qb'></small><noframes id='Sf0qb'>

          <bdo id='Sf0qb'></bdo><ul id='Sf0qb'></ul>
        <i id='Sf0qb'><tr id='Sf0qb'><dt id='Sf0qb'><q id='Sf0qb'><span id='Sf0qb'><b id='Sf0qb'><form id='Sf0qb'><ins id='Sf0qb'></ins><ul id='Sf0qb'></ul><sub id='Sf0qb'></sub></form><legend id='Sf0qb'></legend><bdo id='Sf0qb'><pre id='Sf0qb'><center id='Sf0qb'></center></pre></bdo></b><th id='Sf0qb'></th></span></q></dt></tr></i><div id='Sf0qb'><tfoot id='Sf0qb'></tfoot><dl id='Sf0qb'><fieldset id='Sf0qb'></fieldset></dl></div>
      2. MySQL - 按月计数(包括丢失的记录)

        时间:2023-10-09
      3. <i id='Vb2yQ'><tr id='Vb2yQ'><dt id='Vb2yQ'><q id='Vb2yQ'><span id='Vb2yQ'><b id='Vb2yQ'><form id='Vb2yQ'><ins id='Vb2yQ'></ins><ul id='Vb2yQ'></ul><sub id='Vb2yQ'></sub></form><legend id='Vb2yQ'></legend><bdo id='Vb2yQ'><pre id='Vb2yQ'><center id='Vb2yQ'></center></pre></bdo></b><th id='Vb2yQ'></th></span></q></dt></tr></i><div id='Vb2yQ'><tfoot id='Vb2yQ'></tfoot><dl id='Vb2yQ'><fieldset id='Vb2yQ'></fieldset></dl></div>
          <legend id='Vb2yQ'><style id='Vb2yQ'><dir id='Vb2yQ'><q id='Vb2yQ'></q></dir></style></legend>

            <tfoot id='Vb2yQ'></tfoot>
              <tbody id='Vb2yQ'></tbody>
                  <bdo id='Vb2yQ'></bdo><ul id='Vb2yQ'></ul>

                  <small id='Vb2yQ'></small><noframes id='Vb2yQ'>

                  本文介绍了MySQL - 按月计数(包括丢失的记录)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有这个选择:

                  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
                  

                  并得到这个结果:

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

                  请参阅SQL-Fiddle此处

                  WHERE 子句很重要,因为在我的示例中,我需要它作为从 6 月 1 日开始的当前财政年度.

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

                  如您所见,我没有 7 月、8 月和 11 月的记录.但我需要这些记录总数为零.

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

                  所以我的结果应该是这样的:

                  | 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?

                  推荐答案

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

                  You need to generate all the wanted dates, and then left join your data to the dates. Note also that it is important to put some predicates in the left join's ON clause, and others in the WHERE clause:

                  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) 只计算 created 的非 NULL 值,即当 LEFT JOIN 在任何给定年份不产生任何行时 -月,我们想要 0 作为结果,而不是 1,即我们不想计算 NULL 值.
                  • How does the above work?

                    • CROSS JOIN creates a cartesian product between all available years and all available months. This is what you want, you want all year-month combinations with no gaps.
                    • LEFT JOIN adds all the qualitaet records to the result (if they exist) and joins them to the year-month cartesian product from before. It is important to put prediactes like the status = 1 predicate here.
                    • COUNT(created) counts only non-NULL values of created, i.e. when the LEFT JOIN produces no rows for any given year-month, we want 0 as a result, not 1, i.e. we don't want to count the NULL value.
                    • 以上在您的 ONWHERE 谓词中大量使用了字符串操作和日期时间算法.这不会对大量数据执行.在这种情况下,您最好在 qualitaet 表中预先截断和索引您的年月,并且只对这些值进行操作.

                      The above makes heavy use of string operations and date time arithmetic in your ON and WHERE predicates. This isn't going to perform for lots of data. In that case, you should better pre-truncate and index your year-months in the qualitaet table, and operate only on those values.

                      这篇关于MySQL - 按月计数(包括丢失的记录)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:理解规范化重复 - 我猜我没有 - 添加艺术家和标题 ID 下一篇:我的 sql 代码错误在哪里?

                  相关文章

                    <tfoot id='FqHNd'></tfoot>

                  1. <legend id='FqHNd'><style id='FqHNd'><dir id='FqHNd'><q id='FqHNd'></q></dir></style></legend>
                  2. <small id='FqHNd'></small><noframes id='FqHNd'>

                  3. <i id='FqHNd'><tr id='FqHNd'><dt id='FqHNd'><q id='FqHNd'><span id='FqHNd'><b id='FqHNd'><form id='FqHNd'><ins id='FqHNd'></ins><ul id='FqHNd'></ul><sub id='FqHNd'></sub></form><legend id='FqHNd'></legend><bdo id='FqHNd'><pre id='FqHNd'><center id='FqHNd'></center></pre></bdo></b><th id='FqHNd'></th></span></q></dt></tr></i><div id='FqHNd'><tfoot id='FqHNd'></tfoot><dl id='FqHNd'><fieldset id='FqHNd'></fieldset></dl></div>

                      <bdo id='FqHNd'></bdo><ul id='FqHNd'></ul>