【问题标题】:How to select the total sum of certain table fields based on other joined table conditions?如何根据其他联接表条件选择某些表字段的总和?
【发布时间】:2021-04-22 08:55:49
【问题描述】:

我一直在研究费用跟踪系统。我有三个主要表格:'expenses'、'expense_reports'、'payments'。

我的数据库结构是这样的:

  • “费用”属于一个“费用报告”
  • “expense_reports”有很多“费用”
  • “expense_reports”属于许多“付款”
  • “付款”属于许多“费用报告”

我为“expense_reports”和“payments”表添加了一个数据透视表,即“expense_report_payment”,以处理多对多关系。 'expense_report_payment' 表有 ff 字段:

  • 身份证
  • expense_report_id
  • payment_id
  • 付款

这是我获取费用和付款总额的查询:

SELECT 
  IFNULL(SUM(ex.`amount`), 0) AS total_expenses,
  IFNULL(SUM(erp.`payment`), 0) AS total_payment 
FROM
  `expenses` ex 
  JOIN `expense_reports` er 
    ON er.`id` = ex.`expense_report_id` 
  LEFT JOIN `expense_report_payment` erp 
    ON erp.`expense_report_id` = er.`id` 
  JOIN `payments` p 
    ON p.`id` = erp.`payment_id` 
    AND p.`deleted_at` IS NULL 
    AND p.`cancelled_at` IS NULL 
    AND p.`received_at` IS NOT NULL 
WHERE ex.`deleted_at` IS NULL 
  AND er.`deleted_at` IS NULL 
  AND er.`rejected_at` IS NULL 
  AND er.`cancelled_at` IS NULL 

如果收到付款,我会得到总金额(total_expenses = 100;total_payment = 100)。但是,如果尚未收到付款,则费用和付款的总金额为零。

【问题讨论】:

  • 你必须在加入链的第一个之后使用 LEFT JOIN。 payments 加入到expense_report_payment,所以它在左连接链中,也必须是左连接。

标签: mysql sql mariadb


【解决方案1】:

LEFT JOIN 表。通常,您还应该将右连接表上的WHERE 条件移动到LEFT JOINs ON 子句。试试

SELECT 
  IFNULL(SUM(ex.`amount`), 0) AS total_expenses,
  IFNULL(SUM(erp.`payment`), 0) AS total_payment 
FROM
  `expenses` ex 
  LEFT JOIN `expense_reports` er 
    ON er.`id` = ex.`expense_report_id` 
      AND er.`deleted_at` IS NULL 
      AND er.`rejected_at` IS NULL 
      AND er.`cancelled_at` IS NULL    
  LEFT JOIN `expense_report_payment` erp 
    ON erp.`expense_report_id` = er.`id` 
  LEFT JOIN `payments` p 
    ON p.`id` = erp.`payment_id` 
    AND p.`deleted_at` IS NULL 
    AND p.`cancelled_at` IS NULL 
    AND p.`received_at` IS NOT NULL 
WHERE ex.`deleted_at` IS NULL 
  

【讨论】:

  • 感谢您的回复。我尝试了您的建议,但即使尚未收到付款,它仍然显示付款。这就是为什么我首先将 'payments' 表与 'expense_report_payment' 表一起加入。
【解决方案2】:

感谢大家的帮助。我设法通过在 LEFT JOIN 中加入 'expense_report_payment' 和 'payments' 表来解决这个问题。

SELECT 
  IFNULL(SUM(ex.`amount`), 0) AS total_expenses,
  IFNULL(SUM(erp.payment), 0) AS total_payment
FROM
  `expenses` ex 
  JOIN `expense_reports` er 
    ON er.`id` = ex.`expense_report_id` 
    AND er.`deleted_at` IS NULL 
    AND er.`rejected_at` IS NULL 
    AND er.`cancelled_at` IS NULL 
  LEFT JOIN 
    (SELECT 
      ep.*
    FROM
      `expense_report_payment` ep 
      JOIN `payments` p 
        ON p.`id` = ep.`payment_id`
    WHERE p.`received_at` IS NOT NULL
    AND p.`deleted_at` IS NULL
    AND p.`cancelled_at` IS NULL
    ) AS erp 
    ON erp.expense_report_id = er.`id` 
WHERE ex.`deleted_at` IS NULL 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 2016-02-20
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    相关资源
    最近更新 更多