laraveleloquentsubquery

how to make eloquent subquery select in select


I want to make query in Laravel Eloquent from this raw query, i want to show sum of multiply from satuan and harga columns

SELECT
    rekenings.no_rekening AS no_rekening, 
    rekenings.id AS rekening_id, 
    programs.nama_program AS nama_program, 
    programs.id AS program_id, 
    detail_dpas.nama_barang AS nama_barang, 
    detail_dpas.volume AS volume,
    detail_dpas.satuan AS satuan, 
    detail_spjs.satuan AS satuanSpj, 
    detail_dpas.harga AS harga, 
    detail_spjs.harga AS hargaSpj,
    detail_spjs.catatan AS catatan, 
    detail_dpas.dpa_id AS dpa_id, 
    detail_dpas.id AS detail_dpa_id,
    (
        SELECT SUM(satuan*harga) AS totalspj
        FROM detail_spjs
        WHERE
            rekening_id = rekenings.id
            AND program_id = programs.id
    ),
    (
        SELECT SUM(volume*harga) AS totaldpa
        FROM detail_dpas
        WHERE
            detail_dpas.dpa_id = dpa_id
            AND detail_dpas.id = detail_dpa_id
    )
FROM
    spjs
    JOIN
        detail_spjs
        ON spjs.id = detail_spjs.spj_id
    JOIN
        dpas
        ON dpas.id = detail_spjs.dpa_id
    JOIN
        detail_dpas
        ON dpas.id = detail_dpas.dpa_id
    JOIN
        rekenings
        ON rekenings.id = detail_spjs.rekening_id
    JOIN
        programs
        ON programs.id = detail_spjs.program_id
WHERE
    spjs.id = $id

I have tried this but its doesnt work,

$table_spjs = DB::table('spjs')
    ->join('detail_spjs', 'spjs.id', '=', 'detail_spjs.spj_id')
    ->join('dpas', 'dpas.id', '=', 'detail_spjs.dpa_id')
    ->join('detail_dpas', 'dpas.id', '=', 'detail_dpas.dpa_id')
    ->join('rekenings', 'rekenings.id', '=', 'detail_spjs.rekening_id')
    ->join('programs', 'programs.id', '=', 'detail_spjs.program_id') 
    ->where('spjs.id', '=', $id)   
    ->select(
        'rekenings.no_rekening as no_rekening',
        'rekenings.id as rekening_id',
        'programs.nama_program as nama_program',
        'programs.id as program_id',
        'detail_dpas.nama_barang as nama_barang',
        'detail_dpas.volume as volume',
        'detail_dpas.satuan as satuan', 
        'detail_spjs.satuan as satuanSpj', 
        'detail_dpas.harga as harga',
        'detail_spjs.harga as hargaSpj',
        'detail_spjs.catatan as catatan',
        'detail_dpas.dpa_id as dpa_id',
        'detail_dpas.id as detail_dpa_id',
        DB::Raw('select sum(satuan*harga) as totalspj from detail_spjs where rekening_id=rekenings.id and program_id=programs.id'),
        DB::Raw('select sum(volume*harga) as totaldpa from detail_dpas where detail_dpas.dpa_id=dpa_id and detail_dpas.id=detail_dpa_id')
    )    
    ->get();

maybe there is way to use raw query with laravel


Solution

  • I think the problem is in your raw statements.

    1. The method name is raw, not Raw
    2. You're missing the parenthesis wrapping the subqueries.
    DB::table('spjs')
       ...
       ->select(
          ...
          DB::raw('(select ... program_id = programs.id)'),
          DB::raw('(select ... detail_dpas.id = detail_dpa_id)')
       )
       ->get();
    

    And if that does not work, try adding the alias after the subquery

    DB::table('spjs')
       ...
       ->select(
          ...
          DB::raw('(select ... program_id = programs.id) AS totalspj'),
          DB::raw('(select ... detail_dpas.id = detail_dpa_id) AS totaldpa')
       )
       ->get();
    

    And to answer the question of 'how to do subqueries' with the builder, you can use the addSelect or the selectSub methods.

    // using addSelect
    $table_spjs = DB::table('spjs')
        ...
        ->select(
            ...
            'detail_dpas.id as detail_dpa_id'
        )
        ->addSelect([
            'totalspj' => function (Builder $sub) {
                $sub->selectRaw('SUM(satuan*harga)')
                    ->from('detail_spjs')
                    ->whereColumn('rekening_id', 'rekenings.id')
                    ->whereColumn('program_id', 'programs.id');
            },
            'totaldpa' => function (Builder $sub) {
                $sub->selectRaw('SUM(volume*harga)')
                    ->from('detail_dpas')
                    ->whereColumn('detail_dpas', 'detail_dpas.dpa_id')
                    ->whereColumn('detail_dpa_id', 'details_dpas.id');
            },
        ])
        ->get();
    
    // using selectSub
    $table_spjs = DB::table('spjs')
        ...
        ->select(
            ...
            'detail_dpas.id as detail_dpa_id'
        )
        ->selectSub(
            DB::table('detail_spjs')
                ->selectRaw('SUM(satuan*harga)')
                ->whereColumn('rekening_id', 'rekenings.id')
                ->whereColumn('program_id', 'programs.id'),
            'total_spjs',
        )
        ->selectSub(
            DB::table('detail_dpas')
                ->selectRaw('SUM(volume*harga)')
                ->whereColumn('detail_dpas', 'detail_dpas.dpa_id')
                ->whereColumn('detail_dpa_id', 'details_dpas.id'),
            'totaldpa',
        ])
        ->get();