how to write sql query in laravel

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Complex Queries: How to Write SQL in Laravel

Hello friends! As a senior developer, I often see developers coming to me with complex SQL queries that work perfectly fine in a database editor, but they struggle when trying to translate that logic into the expressive world of an Object-Relational Mapper (ORM) like Laravel Eloquent or the Query Builder. The query you provided is a classic example—it involves calculating a running balance using session variables, which is procedural SQL rather than declarative SQL.

The core challenge here isn't just syntax; it’s understanding the philosophy difference between writing raw SQL and leveraging Laravel's abstraction layer. Let’s break down how we approach this kind of heavy lifting in a robust, maintainable way within a Laravel application.

The Eloquent Philosophy vs. Raw SQL

When you write complex SQL directly, you are telling the database exactly what operations to perform step-by-step. This is powerful for performance tuning on highly specific tasks. However, when building an application with Laravel, our goal shifts slightly: we want to define what data we need (the model structure) and let Laravel/Eloquent handle the how of the database interaction.

For simple SELECT statements, Eloquent makes life incredibly easy. But for advanced calculations like running totals or conditional aggregations, we have a few pathways in Laravel: using raw expressions, leveraging database features, or utilizing Eloquent relationships.

Translating Procedural Logic into Laravel Querying

Your specific query attempts to calculate a running balance:

-- Original Concept (Procedural SQL)
SELECT 
  date,
  memo,
  -- ... complex balance calculation using @b := ...
FROM tbl_bankrecords;

In modern SQL, calculating running totals is best handled using Window Functions or Common Table Expressions (CTEs) rather than session variables. Laravel excels at executing these advanced structures through the DB facade.

Approach 1: Using Database Window Functions (The Preferred Method)

If your database supports standard window functions (like MySQL 8+, PostgreSQL, etc.), this is the cleanest and most performant way to calculate running totals. Instead of trying to trick SQL into using session variables within a simple SELECT, we use functions that operate over ordered sets of rows.

We can translate the concept of calculating a cumulative balance directly:

use Illuminate\Support\Facades\DB;

$results = DB::table('tbl_bankrecords')
    ->select(
        'date',
        'memo',
        // Calculate running total using SUM() over a partition (ordered by date)
        DB::raw('SUM(CASE WHEN drcr = "cr" THEN amount ELSE 0 END) - SUM(CASE WHEN drcr = "dr" THEN amount ELSE 0 END) OVER (ORDER BY date) AS balance')
    )
    ->orderBy('date')
    ->get();

// $results now contains the date, memo, and the calculated running balance for each record.

Notice how we use DB::raw() to inject the complex mathematical logic directly into the query. This keeps the heavy lifting on the database engine, which is where it belongs. For deeper dives into database interactions and best practices in building powerful applications, exploring the documentation at laravelcompany.com is highly recommended.

Approach 2: Using Aggregation for Totals

If you only needed totals per group rather than a running total across all records, standard aggregation methods are superior. For example, if you wanted the total credits and debits for the entire table:

$totals = DB::table('tbl_bankrecords')
    ->select(
        DB::raw('SUM(CASE WHEN drcr = "cr" THEN amount ELSE 0 END) AS total_credits'),
        DB::raw('SUM(CASE WHEN drcr = "dr" THEN amount ELSE 0 END) AS total_debits')
    )
    ->first();

// $totals will contain the grand totals for credits and debits.

Conclusion: Abstraction is Power

The lesson here is that while you can write any SQL query in Laravel using the DB facade, true mastery comes from understanding when to use raw expressions versus leveraging Eloquent's built-in methods. For complex calculations like running balances, pushing the logic into efficient database functions (Window Functions) and letting Laravel execute them is the most robust pattern.

By focusing on these abstractions, you write code that is not only functional but also highly readable, maintainable, and scalable—the hallmark of professional development. Happy coding!