【问题标题】:Mysql Conditional Aggregation Using group_by query and Case to group Month and YearMysql条件聚合使用group_by查询和Case对月份和年份进行分组
【发布时间】:2021-03-17 06:22:50
【问题描述】:

我有一个表格结构,我在其中以以下格式保存数据。

账本金额需要分成两列,并通过求和方程进行分组。

那些receipt_id 不为空他们的ledger_amount的行需要显示为sum(ledger_amount) as credit 具有 payment_id not as null 他们的 ledger_amount 的整行需要显示为 sum(ledger_amount) as debit

这些值需要使用从 receipt_masterpayment_master 表中的日期获取的 "month-year" 进行分组,使用 join using “日期期间”。

除了一个小故障之外,我在开发整体查询方面非常成功。

当我在 “月-年” 上使用“group_by”查询时,它会根据特定条件中较高的行数,在借方/贷方中汇总特定月份的所有记录,我想分开。

检查这张图片。

我目前还没有在这个上应用group_by month,它完美地显示了个人记录。

请看下面当我按月申请 group_by 时会发生什么。

它将所有 ledger_amount 值相加,并在债务方显示为 53819.00,而不是在贷方显示 19500.00 34319.00借方

以下是我对上述结果的查询。

查询第二张图片

SELECT sjm.company_id as sjm_company_id,
    (CASE when sjm.payment_id IS NOT NULL then sum(sjm.ledger_amount) END) AS "CREDIT",
    (CASE when sjm.receipt_id IS NOT NULL then sum(sjm.ledger_amount) END) AS "DEBIT",

    (CASE when sjm.payment_id IS NOT NULL then date_format(sim.payment_date,'%Y-%m')
          when sjm.receipt_id IS NOT NULL then date_format(rim.receipt_date,'%Y-%m') END) AS s_year_month

    FROM ledger_mapper_master sjm
    LEFT JOIN payment_master sim ON sjm.payment_id = sim.payment_id
    LEFT JOIN receipt_master rim ON sjm.receipt_id = rim.receipt_id

    WHERE sjm.sundry_dr_cr_ledger_id IS NOT NULL AND sjm.ledger_id='5991'
    group by ledger_mapper_id
    HAVING s_year_month = '2020-05' AND sjm_company_id = '1' ORDER BY s_year_month;

查询第三张图片 - 两者都相同,只是在 group_by 子句中稍作更改以与 s_year_month

分组
SELECT sjm.company_id as sjm_company_id,
    (CASE when sjm.payment_id IS NOT NULL then sum(sjm.ledger_amount) END) AS "CREDIT",
    (CASE when sjm.receipt_id IS NOT NULL then sum(sjm.ledger_amount) END) AS "DEBIT",

    (CASE when sjm.payment_id IS NOT NULL then date_format(sim.payment_date,'%Y-%m')
          when sjm.receipt_id IS NOT NULL then date_format(rim.receipt_date,'%Y-%m') END) AS s_year_month

    FROM ledger_mapper_master sjm
    LEFT JOIN payment_master sim ON sjm.payment_id = sim.payment_id
    LEFT JOIN receipt_master rim ON sjm.receipt_id = rim.receipt_id

    WHERE sjm.sundry_dr_cr_ledger_id IS NOT NULL AND sjm.ledger_id='5991'
    group by s_year_month
    HAVING s_year_month = '2020-05' AND sjm_company_id = '1' ORDER BY s_year_month;

请告诉我需要进行哪些更改才能将借记部分和贷记部分的金额保留在各自的列中,而不是合并。

即此处的值应为该单行中的 debit_amount:34319credit_amount:19500

【问题讨论】:

  • CASE WHEN sjm.ledger_amount<0 THEN sjm.ledger_amount ELSE 0 END as credit, CASE WHEN sjm.ledger_amount>0 THEN sjm.ledger_amount ELSE 0 END as debit.
  • @Luuk Ledger 金额永远不会为 0 或 null,请查看实际表。我将 ledger_amount 中的两列分隔为借方或贷方,具体取决于receipt_id 和 payment_id 中的非空值

标签: mysql sql database group-by mariadb


【解决方案1】:

我想你想要条件聚合:

SELECT sjm.company_id as sjm_company_id,
       (CASE WHEN sjm.payment_id IS NOT NULL then date_format(sim.payment_date, '%Y-%m')
             WHEN sjm.receipt_id IS NOT NULL then date_format(rim.receipt_date, '%Y-%m')
        END) AS s_year_month
       SUM(CASE when sjm.payment_id IS NOT NULL then sjm.ledger_amount) END AS CREDIT,
       SUM(CASE when sjm.receipt_id IS NOT NULL then sjm.ledger_amount) END AS DEBIT    
FROM ledger_mapper_master sjm LEFT JOIN
     payment_master sim
     ON sjm.payment_id = sim.payment_id LEFT JOIN
     receipt_master rim
     ON sjm.receipt_id = rim.receipt_id
WHERE sjm.sundry_dr_cr_ledger_id IS NOT NULL AND
      sjm.ledger_id = 5991 AND
      sjm_company_id = 1
GROUP BY sjm_company_id, s_year_month
HAVING s_year_month = '2020-05'
ORDER BY s_year_month;

注意事项:

  • 条件聚合将CASE 作为聚合函数的参数。
  • GROUP BY 键应与SELECT 中的未聚合列匹配。
  • “id”列看起来像数字,所以我删除了比较的单引号。如果它们确实是字符串,则使用单引号。

另外,s_year_month 的计算可以简化为:

DATE_FORMAT(COALESCE(sim.payment_date, rim.receipt_date) '%Y-%m') AS s_year_month

但我让你的版本在上面。

【讨论】:

  • 太棒了!这行得通,SUM() 必须按照您的建议位于外侧,但在将其标记为完成之前,我将在周一使用更大的数据集进行验证并确认。
猜你喜欢
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
相关资源
最近更新 更多