mardi 16 juillet 2019

How to use conditional WHERE in raw queries like in eloquent

This is more of a theoretical question. How can you use conditions in a raw laravel query like you do when using eloquent? With simple queries this is not a problem as you can write the query in eloquent but with more complex queries, this would be a nice feature to have (I'm unsure whether it exists or not).

Here is a very simple example. The Eloquent version works but the raw version won't. If this were to be done using a raw query, how would you do it?

Eloquent...

$query = Transaction::orderBy('processingTime', 'desc');

if(isset($request->search['status'])) {
   $query->where('status', '=', $request->search['status']);
}

$query->get();

Raw...

$query = DB::select('SELECT * FROM transactions ORDER BY processingTime DESC');

if(isset($request->search['status'])) {
   $query->where('status', '=', $request->search['status']);
}

$query->get();

The reason I'm asking this question is because I was facing this problem yesterday with a complex query and managed to solve it using collections but I can't help thinking there is an easier more efficient way of doing this. Here's how I solved it last night.

$report = collect(DB::connection('mysql2')->select("SELECT
            t2.holder,
            t2.merchantTransactionId,
            t2.bin,
            t2.last4Digits,
            t3.expDate,
            (CASE WHEN t3.expDate < CURDATE() THEN 'Expired'
            WHEN t3.expDate > CURDATE() THEN 'Due to expire' END) AS expInfo,
            t2.uuid
            FROM transactions AS t2
            INNER JOIN (
                SELECT t1.uuid, t1.holder, t1.bin, t1.last4Digits, LAST_DAY(CONCAT(t1.expiryYear, t1.expiryMonth, '01')) AS expDate
                FROM transactions t1
                JOIN (SELECT t1.merchant_access
                        FROM total_control.users, 
                        JSON_TABLE(merchant_access, '$[*]' COLUMNS (
                            merchant_access VARCHAR(32) PATH '$')
                        ) t1
                        WHERE users.id = :userId
                        ) AS t2
                    ON t1.merchantUuid = t2.merchant_access
                WHERE t1.paymentType = 'RG'
                AND t1.status = 1
            ) t3
            ON t2.uuid = t3.uuid
            WHERE t3.expDate BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND DATE_ADD(CURDATE(), INTERVAL 30 DAY)
            GROUP BY t2.holder, t2.bin, t2.last4Digits
            ORDER BY t2.holder ASC", ['userId' => $request->userId]));

if(isset($request->search['holder'])) {
    $filtered = $report->filter(function($value, $key) use ($request) {
        if(strpos(strtolower($value->holder), strtolower($request->search['holder'])) !== false) {
            return $value;
        }
    });
    return $filtered->all();
}



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire