2015-07-28 11 views
6

come scrivere questa query in laravel 5.1:Come scrivere questo (left join, subquery) in Laravel 5.1?

SELECT p.id, p.title, p.created_at, p.updated_at, u.name, COALESCE(c.comments_count, 0) AS comments_count, COALESCE(pl.status_sum, 0) AS status_sum 

FROM posts p 

LEFT OUTER JOIN users u ON u.id = p.user_id 

LEFT OUTER JOIN (
    SELECT pl.post_id, SUM(pl.status) AS status_sum 
    FROM postslikes pl 
    GROUP BY pl.post_id 
) pl ON pl.post_id = p.id 

LEFT OUTER JOIN (
    SELECT c.post_id, COUNT(*) as comments_count 
    FROM comments c 
    GROUP BY c.post_id 
) c ON c.post_id = p.id ORDER BY comments_count DESC 

ne ho bisogno per la numerazione. Posso eseguire questa interrogazione cruda senza problemi ma il Paginator manualmente dà sempre lo stesso risultato: http://laravel.com/docs/5.1/pagination#manually-creating-a-paginator lo stesso problema qui: http://laravel.io/forum/07-22-2015-laravel-51-manual-pagination-not-working-as-expected

Il mio tentativo senza successo:

DB::table('posts') 
    ->select('posts.id', 'posts.title', 'posts.created_at', 'posts.updated_at', 'users.name', DB::raw('COALESCE(comments.body, 0), COALESCE(postslikes.status, 0)')) 

    ->leftJoin('users', 'users.id', '=', 'posts.user_id') 

    ->leftJoin(DB::raw('SELECT postslikes.post_id, SUM(postslikes.status) FROM postslikes GROUP BY postslikes.post_id'), function($join) 
    { 
     $join->on('postslikes.post_id', '=', 'post.id'); 
    }) 

    ->leftJoin(DB::raw('SELECT comments.post_id, COUNT(*) FROM comments GROUP BY comments.post_id'), function($join) 
    { 
     $join->on('comments.post_id', '=', 'post.id'); 
    }) 

    ->get(); 

Credo che il problema è comments_count e status_sum? Grazie!

+0

Ehi, @baker! La mia risposta qui sotto ti ha mai aiutato? Se è così, per favore considera di accettarlo/svalutarlo. In questo modo puoi aiutare altre persone a cercare una soluzione per un problema simile. –

risposta

7

Per utilizzare subquery con generatore di query di laravel, si dovrebbe aggiungere alla aderire come segue:

->leftJoin(DB::raw("(SELECT [...]) AS p"), 'p.post_id', '=', 'posts.id') 

E 'anche meglio per creare un alias per i campi calcolati, come avete fatto nella vostra domanda prima:

COUNT(*) AS count 

Nonostante queste modifiche, a meno che non mi sbaglio, è possibile iniziare semplificando la query. Drop le sottoquery, in questo modo:

SELECT 
    p.id, 
    p.title, 
    p.created_at, 
    p.updated_at, 
    u.name, 
    COUNT(c.id) AS comments_count, 
    COALESCE(SUM(pl.status), 0) AS status_sum 
FROM 
    posts p 
LEFT OUTER JOIN 
    users u 
ON 
    u.id = p.user_id 
LEFT OUTER JOIN 
    postslikes pl 
ON 
    pl.post_id = p.id 
LEFT OUTER JOIN 
    comments c 
ON 
    c.post_id = p.id 
ORDER BY 
    comments_count DESC 
GROUP BY 
    p.id 

Quindi, con questa nuova query, è possibile utilizzare laravel a costruirlo:

DB::table('posts') 
    ->select([ 
    'posts.id', 
    'posts.title', 
    'posts.created_at', 
    'posts.updated_at', 
    'users.name', 
    DB::raw('COUNT(comments.id) AS comments_count'), 
    DB::raw('COALESCE(SUM(postslikes.status), 0) AS status_sum'), 
    ]) 
    ->leftJoin('users', 'users.id', '=', 'posts.user_id') 
    ->leftJoin('comments', 'comments.post_id', '=', 'posts.id') 
    ->leftJoin('postslikes', 'postslikes.post_id', '=', 'posts.id') 
    ->orderBy('comments_count', 'DESC') 
    ->groupBy('posts.id') 
    ->get(); 

Nota che sto assumendo che abbiate una colonna chiamata id nella vostra comments tabella che è la chiave primaria.