【问题标题】:How to find the number of months missing from January to July of a Year in MySQL如何在 MySQL 中查找一年中从 1 月到 7 月缺少的月数
【发布时间】:2017-03-08 22:23:02
【问题描述】:

我有一个名为 view_uncollected 的视图。

|RemitNo|ID|Employer|  AP_From |  AP_To   |Amount|
|   1   |1 |    a   |2016-01-01|2016-01-31|200.00|
|   2   |1 |    a   |2016-02-01|2016-02-29|200.00|
|   3   |1 |    a   |2016-03-01|2016-03-31|200.00|
|   4   |1 |    a   |2016-04-01|2016-05-31|400.00|
|   5   |1 |    a   |2016-06-01|2016-06-30|200.00|
|   6   |2 |    b   |2016-01-01|2016-03-31|600.00|
|   7   |2 |    b   |2016-04-01|2016-04-30|200.00|
|   8   |2 |    b   |2016-05-01|2016-05-31|200.00|
|   9   |3 |    c   |2016-01-01|2016-01-31|200.00|
|  10   |3 |    c   |2016-01-01|2016-01-31|200.00|
|  11   |3 |    c   |2016-03-01|2016-03-31|200.00|

我需要找出从 2016 年 1 月到 7 月缺少多少 MONTHS。

根据上表有一些复杂的情况:

  • 雇主 (a) 仅在 2016 年 1 月至 2016 年 6 月期间支付。它缺少一个月。
  • 雇主 (b) 仅在 2016 年 1 月至 2016 年 5 月期间支付。它缺少 2 个月。
  • 雇主 (c) 支付了 1 月 (2x) 和 3 月的费用。它缺少5个月。 我们不会将 1 月的另一笔付款视为 2 月。

我如何计算每个雇主失踪的月份?

我所做的是使用这个 7 - COUNT(RemitNo) GROUP BY ID 因为我认为每个 ONE ROW = ONE MONTH 。但是在查看我的结果后,一些雇主有ONE ROW = 2 MONTHS,比如RemitNo = 4。我当时就知道这是错误的,因为它只计算行数而不是月数。

这背后的原因是,我们需要知道 2016 年 1 月至 7 月期间有多少未收到的汇款。

感谢您的建议和cmets。抱歉这个新手问题

【问题讨论】:

  • 你需要一个日历表,google一下,网上有很多教程
  • 只是想知道如果在同一笔付款上支付几个月,金额不应该大于一个月吗?
  • @JuanCarlosOropeza 是的,先生,我现在将编辑我的示例。
  • 您还应该检查描述,因为数据显示a 分五期支付了所有 6 个月,而b 只错过了三期支付的一期

标签: mysql date datetime count


【解决方案1】:

这是基本查询,可让您获得已支付的月份。

DEMO

SELECT ID, month
FROM YourTable T
JOIN (    
        SELECT 'JAN' as month,'2016-01-01' as start,'2016-01-31' as end UNION ALL
        SELECT 'FEB' as month,'2016-02-01' as start,'2016-02-29' as end UNION ALL
        SELECT 'MAR' as month,'2016-03-01' as start,'2016-03-31' as end UNION ALL
        SELECT 'APR' as month,'2016-04-01' as start,'2016-04-30' as end UNION ALL
        SELECT 'MAY' as month,'2016-05-01' as start,'2016-05-31' as end UNION ALL
        SELECT 'JUN' as month,'2016-06-01' as start,'2016-06-30' as end UNION ALL
        SELECT 'JUL' as month,'2016-07-01' as start,'2016-07-31' as end 
    ) M
    ON T.AP_From <= M.end 
   AND T.AP_To >= M.start;

部分结果:

最终查询:

SELECT ID, COUNT(month) as payed
FROM 
    (
      <First Query>
     ) F
GROUP BY ID;  

输出

【讨论】:

  • 先生,SELECT 'MAY' as month,'2016-05-01' as start,'2016-05-31' as end UNION ALL 失踪了吗?
  • 先生,我在RemitNo 4 中的示例怎么样?它来自2016-04-01 - 2016-05-31 它是从四月到五月
  • 怎么样?怎么了?如果您获得部分结果,您将在那里看到两个月
【解决方案2】:

如何计算两个日期之间的差异并对所有行求和。

SELECT Employer, 7-SUM(TIMESTAMPDIFF(MONTH, AP_from, DATE_ADD(AP_to,INTERVAL 1 DAY))) as missingmonth 
FROM tablename
GROUP BY Employer;

【讨论】:

    【解决方案3】:

    考虑以下...

    SELECT * FROM my_table;
    +---+
    | i |
    +---+
    | 2 |
    | 3 |
    | 5 |
    | 8 |
    +---+
    
    SELECT 7 - COUNT(DISTINCT i) x FROM my_table WHERE i BETWEEN 1 AND 7;
    +---+
    | x |
    +---+
    | 4 |
    +---+
    

    出于本示例的目的,我使用了一个简单的整数列,我将其称为 i,但它也可以是一个日期。其他人建议您需要某种日历或实用表。我证明你没有。我只是从应该存在的数字中减去(不同的)月数/整数。

    【讨论】:

    • i 代表什么?
    • 就本示例而言,我使用了一个简单的整数列,我将其称为 i,但它也可以是一个日期。其他人建议您需要某种日历或实用表。我证明你没有。我只是从应该存在的数字中减去(不同的)月数/整数。
    【解决方案4】:
    |RemitNo|ID|Employer|  AP_From |  AP_To   |Amount|
    |   1   |1 |    a   |2016-01-01|2016-01-31|200.00|
    |   2   |1 |    a   |2016-02-01|2016-02-29|200.00|
    |   3   |1 |    a   |2016-03-01|2016-03-31|200.00|
    |   4   |1 |    a   |2016-04-01|2016-05-31|400.00|
    |   5   |1 |    a   |2016-06-01|2016-06-30|200.00|
    |   6   |2 |    b   |2016-01-01|2016-03-31|600.00|
    |   7   |2 |    b   |2016-04-01|2016-04-30|200.00|
    |   8   |2 |    b   |2016-05-01|2016-05-31|200.00|
    |   9   |3 |    c   |2016-01-01|2016-01-31|200.00|
    |  10   |3 |    c   |2016-01-01|2016-01-31|200.00|
    |  11   |3 |    c   |2016-03-01|2016-03-31|200.00|
    

    根据上表有一些复杂的情况:

    • 雇主 (a) 仅在 2016 年 1 月至 2016 年 6 月期间支付。一个月不见了 从中。
    • 雇主 (b) 仅在 2016 年 1 月至 2016 年 5 月期间支付。 2个月是 从中丢失。
    • 雇主 (c) 支付了 1 月 (2x) 和 3 月的费用。 5个月是 从中丢失。我们不会将 1 月份的另一笔付款视为 二月。

    现在,在我看来,雇主 a 已全额支付了从 2016-01-012016-06-30 的款项,并且他在 June 月份的付款是在 @987654325 支付的@。如果我们选择按雇主分组的总和,我们会得到 ​​p>

    |Employer|Sum    |
    |   a    |1200.00|
    |   b    |1000.00|
    |   c    | 600.00|
    

    现在,如果我们假设每个雇主每月需要支付 200 美元,并且从 2016-01-012016-06-30 的累积月数为 6 个月,那么最合乎逻辑的查询将是。

    SELECT employer, (200 * 6) - sum(amount) as balance, sum(amount) / 200 as months_due FROM table WHERE AP_FROM =&gt; '2016-01-01' AND AP_To &lt;= '2016-06-30' HAVING (200 * 6) - sum(amount) &gt; 0;

    我没有测试过这个脚本,但我相信这正是你所需要的。

    编辑: 我相信这已经解决了,尽管没有答案被标记为正确。 :]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      相关资源
      最近更新 更多