简体   繁体   中英

Laravel - How to add a JOIN and CASE-WHEN using Query Builder or Eloquent?

I have the following working, raw SQL statement that I'm finding incredibly tough to convert into PHP, using Laravel/Query Builder/Eloquent.

SELECT aa.filepath, 
       aa.filename, 
       inst.instrument, 
       rl.raga, 
       ks.keysig, 
       aa.id    AS AAID, 
       likes.id AS LikesID 
FROM   (audioassets aa) 
       INNER JOIN instruments inst 
               ON aa.instrument_id = inst.id 
       INNER JOIN keysigs ks 
               ON aa.keysig_id = ks.id 
       LEFT JOIN ragalist rl 
              ON aa.raga_id = rl.i 
       LEFT JOIN likes 
              ON aa.id = likes.audioassets_id 
                 AND CASE likes.user_id 
                       WHEN 1 THEN true 
                       ELSE false 
                     END 
WHERE  ks.keysig LIKE '%' 
       AND inst.instrument LIKE '%';

My Notes:

  • the issue I'm encountering is with trying to get the CASE-WHEN code to work in Laravel

  • the "1" after "WHEN" is meant to be a variable, so it's just for testing right now

  • all I'm trying to do is display a list of files on a "dashboard" AND show which files the currently logged in user has "liked" (no one else's likes)

Here is my Laravel Eloquent code:

$query = \App\Audioassets::where('instruments.instrument', 'LIKE', "%$ddinstselected%")
        ->where('keysigs.keysig', 'LIKE', "%$ddkeyselected%")
        ->join('instruments', 'audioassets.instrument_id', '=', 'instruments.id')
        ->leftjoin('ragalist', 'audioassets.raga_id', '=', 'ragalist.id')
        ->join('keysigs', 'audioassets.keysig_id', '=', 'keysigs.id')
        ->leftjoin('likes', 'likes.audioassets_id', '=', 'audioassets.id')
        ->where('likes.user_id', '=', $authuserid)
        ->select('audioassets.filepath', 'audioassets.filename', 
'instruments.instrument', 'ragalist.raga', 'keysigs.keysig', 'audioassets.id', 'likes.id as likesid');

This works fine in Laravel but does not incorporate the CASE-WHEN SQL, so all the "likes" are shown for all the users.

Any help would be greatly appreciated!

You can try with below query

myFriendsData = DB::table('audioassets as aa')
    ->where('ks.keysig', 'LIKE', '%')
    ->join('instruments', 'audioassets.instrument_id', '=', 'instruments.id')
    ->leftjoin('ragalist', 'audioassets.raga_id', '=', 'ragalist.id')
    ->join('keysigs', 'audioassets.keysig_id', '=', 'keysigs.id')
    ->join('likes ',audioassets.id = likes.audioassets_id, function() {})
    ->whereRaw(
        '( 
            CASE 
                 WHEN likes.user_id = 1 THEN true ELSE false     
            END
        )'
    )
    ->select('audioassets.filepath', 'audioassets.filename','instruments.instrument', 'ragalist.raga', 'keysigs.keysig', 'audioassets.id', 'likes.id as likesid');
    ->get();

You can use advance join clauses and DB::raw() :

<?php
$query = \App\Audioassets::where('instruments.instrument', 'LIKE', "%$ddinstselected%")
    ->where('keysigs.keysig', 'LIKE', "%$ddkeyselected%")
    ->join('instruments', 'audioassets.instrument_id', '=', 'instruments.id')
    ->leftjoin('ragalist', 'audioassets.raga_id', '=', 'ragalist.id')
    ->join('keysigs', 'audioassets.keysig_id', '=', 'keysigs.id')
    // Use join clause.
    ->leftJoin('likes', function ($join) {
        $join->on('aa.id', '=', 'likes.audioassets_id')
             // CASE WHEN by DB::raw()
             ->on(DB::raw('CASE likes.user_id WHEN 1 THEN true ELSE false'));
    )
    ->where('likes.user_id', '=', $authuserid)
    ->select(
        'audioassets.filepath',
        'audioassets.filename', 
        'instruments.instrument',
        'ragalist.raga',
        'keysigs.keysig',
        'audioassets.id',
        'likes.id as likesid'
    );

Join Clause API Reference: Illuminate\\Database\\Query\\JoinClause | Laravel API

Thanks for all the help! I didn't get back around to responding to all the great helpers in this thread, but the answer was a mix of the two answers provided above. Here's the final code that works flawlessly:

$query = \App\Audioassets::where('instruments.instrument', 'LIKE', "%$ddinstselected%")
->where('keysigs.keysig', 'LIKE', "%$ddkeyselected%")
->leftJoin('likes', function ($join) use ($authuserid) {
    $join->on('audioassets.id', '=', 'likes.audioassets_id');
    $join->whereRaw(
        '(
                CASE
                    WHEN likes.user_id=? THEN true ELSE false
                END
        )'
        , [$authuserid]);
    })
->join('instruments', 'audioassets.instrument_id', '=', 'instruments.id')
->leftjoin('ragalist', 'audioassets.raga_id', '=', 'ragalist.id')
->join('keysigs', 'audioassets.keysig_id', '=', 'keysigs.id')
->select('audioassets.filepath', 'audioassets.filename', 'instruments.instrument', 'ragalist.raga', 'keysigs.keysig', 'audioassets.id', 'likes.id as likesid');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM