2015-07-28 21 views
6

Nasıl laravel 5.1 bu sorguyu yazmak için:Bunu nasıl yazacağım (sol birleştirme, alt sorgu) 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 

Ben Sayfalandırma için lazım. Ben herhangi bir sorun olmadan bu sorgu çiğ gerçekleştirebilir fakat el paginator hep aynı sonuçları verir: burada http://laravel.com/docs/5.1/pagination#manually-creating-a-paginator aynı sorun: başarılı olamadı http://laravel.io/forum/07-22-2015-laravel-51-manual-pagination-not-working-as-expected

girişimim:

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(); 

Sorunun düşünüyorum comments_count ve status_sum? Teşekkürler! aşağıdaki gibi

+0

Hey, @baker! Cevabım size hiç yardımcı oldu mu? Eğer öyleyse, lütfen kabul etmeyi/yükseltmeyi düşünün. Bunu yapmak, benzer bir sorun için çözüm arayan diğer insanlara yardımcı olabilir. –

cevap

7

laravel sorgu oluşturucu ile alt sorgular kullanmak için, katılmak eklemek gerekir:

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

ham sorguda olduğu gibi, hesaplanan alanlar için bir takma ad oluşturmak da iyidir:

COUNT(*) AS count 

Bu değişikliklere rağmen, yanılmadıkça, sorgunuzu daha basit hale getirerek başlayabilirsiniz. alt sorgular Bırak, bu şekilde:

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 

Sonra, bu yeni sorgusu ile, bunu inşa etmek laravel kullanabilirsiniz: Ben de id adlı bir sütun var sanıyorum

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(); 

Not senin Birincil anahtar olan comments tablo.