Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

syntaxerron's avatar

Add another condition on LEFT JOIN

I have been working on an expense tracking system. I have three main tables: 'expenses', 'expense_reports', 'payments'.

I structured my database like this:

  • 'expenses' belongs to one 'expense_reports'
  • 'expense_reports' has many 'expenses'
  • 'expense_reports' belongs to many 'payments'
  • 'payments' belongs to many 'expense_reports'

I added a pivot table namely 'expense_report_payment' for 'expense_reports' and 'payments' tables to handle many-to-many relationships. 'expense_report_payment' table has the ff fields:

  • id
  • expense_report_id
  • payment_id
  • payment

This is my query to fetch the total sum of expenses and 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 

I did know how to do leftJoin but don't know how to add other condition with it.

$total_summary = DB::table('expenses')
            ->select(DB::raw('IFNULL(sum(expenses.amount), 0) as total_expenses'))
            ->join("expense_reports", "expense_reports.id", "=", "expenses.expense_report_id")
            ->where(DB::raw("expenses.deleted_at"), null)
            ->first();
0 likes
2 replies
SilenceBringer's avatar
Level 55

@coderron look here https://laravel.com/docs/8.x/queries#advanced-join-clauses

            ->join("expense_reports", function ($query) {
                $query->on("expense_reports.id", "=", "expenses.expense_report_id")
                    ->whereNotNull('expense_reports.deleted_at')
                    ->whereNotNull('expense_reports.rejected_at')
                    ->whereNotNull('expense_reports.cancelled_at');
            })

and subquery joins https://laravel.com/docs/8.x/queries#subquery-joins for the second

$expenseReportPayment = DB::table('expense_report_payment')
    ->select(`expense_report_payment.*`)
    ->join("payments", "payments.id", "=", "expense_report_payment.payment_id")
    ->whereNotNull('payments.deleted_at')
    ->whereNotNull('payments.rejected_at')
    ->whereNotNull('payments.cancelled_at');

and then connect it to your query

        ->joinSub($expenseReportPayment , 'erp', function ($join) {
            $join->on('erp.expense_report_id', '=', 'expense_reports.id');
        })
1 like

Please or to participate in this conversation.