• 27-06-2018, 01:14:31
    #1
    Reveloper
    Merhaba,

    yorumlar ve begeniler adında iki tablomuz olduğunu düşünelim; Beğenirlerde bir sütünumuz mevcut "tip" diye 0 ise "AS unlike" 1 ise "AS like" yapacağız. ancak count olarak almamız gerekiyor örneklem verirsek;

    yorumlar;
    id - yorum

    begeniler
    id - tip

    yorumlar
    --1--güzel
    --2--süper olmuş
    --3--gibi gibi

    begeniler
    YORUMID--TIP
    1--1
    1--0
    3--1
    3--1
    3--0

    Benim query bana şunu verecek

    yorum_id - yorum -- like -- unlike

    1 -- güzel -- 1 -- 1
    2 -- süper olmuş -- 0 -- 0
    3 -- gibi gibi -- 2 -- 1

    Ancak laravelde hiçbir türlü joine yediremedim bunu daha önce yapmış olan varmı bu şekilde ?
  • 27-06-2018, 01:39:23
    #2
    Bana bu tabloların sql halini gönderirseniz sorgu cümlesini yazıp gönderirim size
  • 27-06-2018, 03:10:00
    #3
    Reveloper
    ahmethekim14 adlı üyeden alıntı: mesajı görüntüle
    Bana bu tabloların sql halini gönderirseniz sorgu cümlesini yazıp gönderirim size
    Sistemin patladığı yer multiple join oluyor 6 tane daha join yapıyor çünkü tablo :/ ben basite indirgeyerek anlattım;

    CREATE TABLE `begeniler` (
      `yorum_id` int(11) NOT NULL,
      `tip` enum('0','1') NOT NULL,
      `user_id` int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    INSERT INTO `begeniler` (`yorum_id`, `tip`, `user_id`) VALUES
    (1, '1', 536),
    (3, '0', 232),
    (3, '0', 423),
    (4, '1', 111);
    CREATE TABLE `yorumlar` (
      `id` int(11) NOT NULL,
      `uid` int(11) NOT NULL,
      `yorum` text NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    INSERT INTO `yorumlar` (`id`, `uid`, `yorum`) VALUES
    (1, 4453, 'Güzel bir mesaj'),
    (2, 464, 'olmu? sankii'),
    (3, 464, 'olmus sankii'),
    (4, 646, 'veni vidi vici');
    ALTER TABLE `yorumlar`
      ADD PRIMARY KEY (`id`);
    ALTER TABLE `yorumlar`
      MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
    COMMIT;
  • 27-06-2018, 11:11:27
    #4
    ztk
    Kimlik doğrulama veya yönetimden onay bekliyor.
    SELECT
       yorumlar.id,
       yorumlar.yorum,
       sum(case when begeniler.tip = '0' then 1 else 0 end) as dislike,
       sum(case when begeniler.tip = '1' then 1 else 0 end) as like
    FROM
      yorumlar
    LEFT JOIN
      begeniler ON yorumlar.id = begeniler.yorum_id
    GROUP BY yorumlar.id, yorumlar.yorum
    ORDER BY id ASC
    
    // Laravel Versiyonu
    DB::table('yorumlar')
    ->select(
       'yorumlar.id',
       'yorumlar.yorum',
       DB::raw("sum(case when begeniler.tip = '0' then 1 else 0 end) as dislike"),
       DB::raw("sum(case when begeniler.tip = '1' then 1 else 0 end) as like")
    )
    ->leftJoin('begeniler', 'yorumlar.id', '=', 'begeniler.yorum_id')
    ->groupBy('yorumlar.id','yorumlar.yorum')
    ->orderBy('id','ASC')
    ->get();
    denedim.
    tablo ve kolon isimleri tutmayabilir kendinize göre düzenleyin.
  • 27-06-2018, 12:39:16
    #5
    Reveloper
    ztk adlı üyeden alıntı: mesajı görüntüle
    SELECT
       yorumlar.id,
       yorumlar.yorum,
       sum(case when begeniler.tip = '0' then 1 else 0 end) as dislike,
       sum(case when begeniler.tip = '1' then 1 else 0 end) as like
    FROM
      yorumlar
    LEFT JOIN
      begeniler ON yorumlar.id = begeniler.yorum_id
    GROUP BY yorumlar.id, yorumlar.yorum
    ORDER BY id ASC
    
    // Laravel Versiyonu
    DB::table('yorumlar')
    ->select(
       'yorumlar.id',
       'yorumlar.yorum',
       DB::raw("sum(case when begeniler.tip = '0' then 1 else 0 end) as dislike"),
       DB::raw("sum(case when begeniler.tip = '1' then 1 else 0 end) as like")
    )
    ->leftJoin('begeniler', 'yorumlar.id', '=', 'begeniler.yorum_id')
    ->groupBy('yorumlar.id','yorumlar.yorum')
    ->orderBy('id','ASC')
    ->get();
    denedim.
    tablo ve kolon isimleri tutmayabilir kendinize göre düzenleyin.
    anlamadığım şey şu count yaparken işlem görmezken sum u nasıl kabul etti ?
  • 27-06-2018, 15:03:32
    #6
    Burti adlı üyeden alıntı: mesajı görüntüle
    anlamadığım şey şu count yaparken işlem görmezken sum u nasıl kabul etti ?
    Siz sorgunuzu nasıl yazdınız bilmiyorum ama burada count yaparsanız istediğiniz sonucu alamazsınız bir çok subquery yani alt sorgu yazmanız gerekir.
    Count size satır sayısını döndürür. Örneğin SELECT COUNT('begeniler.tip') as dislike WHERE begeniler.tip = 0 bu sorgu size dislike sayısını verecek ama like için aynısını yeniden yazmanız gerekecek bunları joinle birleştirecek falan feşmekan.. Bu iş olmuyor böyle.

    Sum ile yaptığımız işlem,
    SUM(CASE WHEN begeniler.tip = "0" THEN 1 ELSE 0 END) as dislike
    burada aslında sayıyoruz ama manuel sayıyoruz. Yani diyoruz ki beğenilerin tipi 0 ise bu kolonun değerini 1 olarak gör ve tüm satırlarda bu şekilde olanları topla.
    Diğerinde de beğenilerin tipi 1 ise bu kolonu 1 olarak gör tüm satırlarda bu şekilde olanları topla. Sonucu bu şekilde elde ediyoruz.
    SUM(CASE WHEN begeniler.tip = "0" THEN 1 ELSE 0 END) as dislike
    kırmızıya boyadığım 0 sizi aldatmasın. Orada siz mesela varchar kullanmış olsaydınız ve tip = 0 yerine tip = dislike demiş olsaydınız sorguyu şöyle yapabilirdiniz.
    SUM(CASE WHEN begeniler.tip = "dislike" THEN 1 ELSE 0 END) as dislike
    böylece siz tip'i dislike olan hücrelerin değerini 1 olarak algıla ve sonra bu hücreleri topla demiş olacaktınız. Mantık bu.

    İyi forumlar.
  • 27-06-2018, 17:52:41
    #7
    ztk adlı üyeden alıntı: mesajı görüntüle
    Siz sorgunuzu nasıl yazdınız bilmiyorum ama burada count yaparsanız istediğiniz sonucu alamazsınız bir çok subquery yani alt sorgu yazmanız gerekir.
    Count size satır sayısını döndürür. Örneğin SELECT COUNT('begeniler.tip') as dislike WHERE begeniler.tip = 0 bu sorgu size dislike sayısını verecek ama like için aynısını yeniden yazmanız gerekecek bunları joinle birleştirecek falan feşmekan.. Bu iş olmuyor böyle.

    Sum ile yaptığımız işlem,
    SUM(CASE WHEN begeniler.tip = "0" THEN 1 ELSE 0 END) as dislike
    burada aslında sayıyoruz ama manuel sayıyoruz. Yani diyoruz ki beğenilerin tipi 0 ise bu kolonun değerini 1 olarak gör ve tüm satırlarda bu şekilde olanları topla.
    Diğerinde de beğenilerin tipi 1 ise bu kolonu 1 olarak gör tüm satırlarda bu şekilde olanları topla. Sonucu bu şekilde elde ediyoruz.
    SUM(CASE WHEN begeniler.tip = "0" THEN 1 ELSE 0 END) as dislike
    kırmızıya boyadığım 0 sizi aldatmasın. Orada siz mesela varchar kullanmış olsaydınız ve tip = 0 yerine tip = dislike demiş olsaydınız sorguyu şöyle yapabilirdiniz.
    SUM(CASE WHEN begeniler.tip = "dislike" THEN 1 ELSE 0 END) as dislike
    böylece siz tip'i dislike olan hücrelerin değerini 1 olarak algıla ve sonra bu hücreleri topla demiş olacaktınız. Mantık bu.

    İyi forumlar.
    merhaba,

    2 adet subquery yapıldığı durumda
    SELECT
    yorumlar.id,
    yorumlar.yorum,
    (SELECT COUNT(*) as dislike WHERE begeniler.yorum_id=yorumlar.yorum_id begeniler.tip = '0') as a,
    (SELECT COUNT(*) as dislike WHERE begeniler.yorum_id=yorumlar.yorum_id begeniler.tip = '1') as b...

    ve sizin yazdığınız join işlemi gerçekleştirip sum ile yaptığınız hesaplama sorgularının analiz sonuçlarına göre değerlendirip "...falan feşmekan.. Bu iş olmuyor böyle." yorumunu yaparsak daha doğru olur.

    https://dev.mysql.com/doc/refman/5.7/en/explain.html

    en basitinden explain sorgularını ekleyin beraber inceleyelim.

    analiz için minunum 20 satır ve beğeni sayısı 20 satır için 500-1000 adet beğeni/beğenmeme durumları olsun. kesin yorumu beraber yapalım.

    iyi çalışmalar
  • 28-06-2018, 01:33:40
    #8
    Reveloper
    ztk adlı üyeden alıntı: mesajı görüntüle
    SELECT
       yorumlar.id,
       yorumlar.yorum,
       sum(case when begeniler.tip = '0' then 1 else 0 end) as dislike,
       sum(case when begeniler.tip = '1' then 1 else 0 end) as like
    FROM
      yorumlar
    LEFT JOIN
      begeniler ON yorumlar.id = begeniler.yorum_id
    GROUP BY yorumlar.id, yorumlar.yorum
    ORDER BY id ASC
    
    // Laravel Versiyonu
    DB::table('yorumlar')
    ->select(
       'yorumlar.id',
       'yorumlar.yorum',
       DB::raw("sum(case when begeniler.tip = '0' then 1 else 0 end) as dislike"),
       DB::raw("sum(case when begeniler.tip = '1' then 1 else 0 end) as like")
    )
    ->leftJoin('begeniler', 'yorumlar.id', '=', 'begeniler.yorum_id')
    ->groupBy('yorumlar.id','yorumlar.yorum')
    ->orderBy('id','ASC')
    ->get();
    denedim.
    tablo ve kolon isimleri tutmayabilir kendinize göre düzenleyin.
    ztk adlı üyeden alıntı: mesajı görüntüle
    Siz sorgunuzu nasıl yazdınız bilmiyorum ama burada count yaparsanız istediğiniz sonucu alamazsınız bir çok subquery yani alt sorgu yazmanız gerekir.
    Count size satır sayısını döndürür. Örneğin SELECT COUNT('begeniler.tip') as dislike WHERE begeniler.tip = 0 bu sorgu size dislike sayısını verecek ama like için aynısını yeniden yazmanız gerekecek bunları joinle birleştirecek falan feşmekan.. Bu iş olmuyor böyle.

    Sum ile yaptığımız işlem,
    SUM(CASE WHEN begeniler.tip = "0" THEN 1 ELSE 0 END) as dislike
    burada aslında sayıyoruz ama manuel sayıyoruz. Yani diyoruz ki beğenilerin tipi 0 ise bu kolonun değerini 1 olarak gör ve tüm satırlarda bu şekilde olanları topla.
    Diğerinde de beğenilerin tipi 1 ise bu kolonu 1 olarak gör tüm satırlarda bu şekilde olanları topla. Sonucu bu şekilde elde ediyoruz.
    SUM(CASE WHEN begeniler.tip = "0" THEN 1 ELSE 0 END) as dislike
    kırmızıya boyadığım 0 sizi aldatmasın. Orada siz mesela varchar kullanmış olsaydınız ve tip = 0 yerine tip = dislike demiş olsaydınız sorguyu şöyle yapabilirdiniz.
    SUM(CASE WHEN begeniler.tip = "dislike" THEN 1 ELSE 0 END) as dislike
    böylece siz tip'i dislike olan hücrelerin değerini 1 olarak algıla ve sonra bu hücreleri topla demiş olacaktınız. Mantık bu.

    İyi forumlar.
    CoreDeluxe adlı üyeden alıntı: mesajı görüntüle
    merhaba,

    2 adet subquery yapıldığı durumda
    SELECT
    yorumlar.id,
    yorumlar.yorum,
    (SELECT COUNT(*) as dislike WHERE begeniler.yorum_id=yorumlar.yorum_id begeniler.tip = '0') as a,
    (SELECT COUNT(*) as dislike WHERE begeniler.yorum_id=yorumlar.yorum_id begeniler.tip = '1') as b...

    ve sizin yazdığınız join işlemi gerçekleştirip sum ile yaptığınız hesaplama sorgularının analiz sonuçlarına göre değerlendirip "...falan feşmekan.. Bu iş olmuyor böyle." yorumunu yaparsak daha doğru olur.

    https://dev.mysql.com/doc/refman/5.7/en/explain.html

    en basitinden explain sorgularını ekleyin beraber inceleyelim.

    analiz için minunum 20 satır ve beğeni sayısı 20 satır için 500-1000 adet beğeni/beğenmeme durumları olsun. kesin yorumu beraber yapalım.

    iyi çalışmalar

    Laradan titana çevirdim başka bi sebepten dolayı;

    $comments = Model::run('Comments')->type('series')->db()
                ->select("comments.*,users.*,series.*,sum(case when comments_like.like_type = '0' then 1 else 0 end) as dislike,sum(case when comments_like.like_type = '1' then 1 else 0 end) as likes")
                ->innerJoin('users', 'comments.user_id=users.user_id')
                ->innerJoin('series', 'comments.post_id=series.series_id')
                ->leftJoin('comments_like', 'comments.id=comments_like.comment_id')
                ->groupBy('comments.id')
                ->orderBy('comments.id', 'DESC')
                ->getAll();
    SELECT comments.*,users.*,series.*,sum(case when comments_like.like_type = '0' then 1 else 0 end) as dislike,sum(case when comments_like.like_type = '1' then 1 else 0 end) as likes FROM comments  INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series'  GROUP BY comments.id   ORDER BY comments.id DESC
    Yok hocam baz alamadık. Baz olarak comments_like alanını alıyor. kafayı kırdım iyice


    @CoreDeluxe; seninkide baz olarak likes ı alıyor;

    SELECT comments.*,users.*,series.*,(SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 0) as aa,
    (SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 1) as bb FROM comments  INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series'  GROUP BY comments.id   ORDER BY comments.id DESC
  • 28-06-2018, 08:29:56
    #9
    Burti adlı üyeden alıntı: mesajı görüntüle
    Laradan titana çevirdim başka bi sebepten dolayı;

    $comments = Model::run('Comments')->type('series')->db()
                ->select("comments.*,users.*,series.*,sum(case when comments_like.like_type = '0' then 1 else 0 end) as dislike,sum(case when comments_like.like_type = '1' then 1 else 0 end) as likes")
                ->innerJoin('users', 'comments.user_id=users.user_id')
                ->innerJoin('series', 'comments.post_id=series.series_id')
                ->leftJoin('comments_like', 'comments.id=comments_like.comment_id')
                ->groupBy('comments.id')
                ->orderBy('comments.id', 'DESC')
                ->getAll();
    SELECT comments.*,users.*,series.*,sum(case when comments_like.like_type = '0' then 1 else 0 end) as dislike,sum(case when comments_like.like_type = '1' then 1 else 0 end) as likes FROM comments  INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series'  GROUP BY comments.id   ORDER BY comments.id DESC
    Yok hocam baz alamadık. Baz olarak comments_like alanını alıyor. kafayı kırdım iyice


    @CoreDeluxe; seninkide baz olarak likes ı alıyor;

    SELECT comments.*,users.*,series.*,(SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 0) as aa,
    (SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 1) as bb FROM comments  INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series'  GROUP BY comments.id   ORDER BY comments.id DESC
    ben arkadaşın iki yaklışımı analiz etmeden birisi için olmaz/iyi olmaz gibisinden yorum yaptığı için analiz edelim öyle karar verelim diye cevap yazdım.

    siz subquery denediğiniz için sorgunuzu tam olarak analiz etme şansım yok ama veri tipine bakarak bariz gözüken hatayı söyleyebilirim.

    enum('0','1') veritipi için ayrıntıya girmeden

    '0' karşılığı 1
    '1' karşılığı 2 dir (tırnak içinde yazdığım metin, direk 1,2 yazdıklarım integer)

    SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 0

    comments_like.like_type = 0 bunun karşılığı yoktur, bu sorgu her zaman 0 sonucunu üretir.

    istemsizce kritik bir duruma el atmışsınız.

    SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 1

    burada (like_type = 1) beğeni sonucu bekliyorsunuz ama 1 ifadesinin karşığı like_type = '0' beğenmeme durumudur.



    SELECT comments.*,users.*,series.*,(SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = '0') as aa,
    (SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = '1') as bb FROM comments INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series' GROUP BY comments.id ORDER BY comments.id DESC


    ile

    SELECT comments.*,users.*,series.*,(SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 1) as aa,
    (SELECT COUNT(*) as dislike FROM comments_like WHERE comments_like.comment_id=comments.id AND comments_like.like_type = 2) as bb FROM comments INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series' GROUP BY comments.id ORDER BY comments.id DESC


    sorguları aynıdır

    iyi çalışmalar

    ----------

    arkadaşın yazdığı sorgu için de bişeyler yazıcaktım es geçmişim ekliyorum.

    SELECT comments.*,users.*,series.*,sum(case when comments_like.like_type = '0' then 1 else 0 end) as dislike,sum(case when comments_like.like_type = '1' then 1 else 0 end) as likes FROM comments INNER JOIN users ON comments.user_id=users.user_id INNER JOIN series ON comments.post_id=series.series_id LEFT JOIN comments_like ON comments.id=comments_like.comment_id WHERE comments.type='series' GROUP BY comments.id ORDER BY comments.id DESC

    sorgu hatasız gözüküyor fakat olabilecek durumu belirtiyim.

    LEFT JOIN ifadesi var yani NULL değer gelebilir.

    comments_like.like_type = '0'
    NULL = '0' diye bir yaklaşım doğru değildir. bu durumlarda = operatörü kullanılmaz. <=> operatörü kullanılır.

    sum(case when comments_like.like_type <=> '0' then 1 else 0 end) as dislike,sum(case when comments_like.like_type <=> '1' then 1 else 0 end)

    bir de yukarı bahsettiğim şekilde deneyin.

    sum(case when comments_like.like_type+0 <=> 1 then 1 else 0 end) as dislike,sum(case when comments_like.like_type+0 <=> 2 then 1 else 0 end)

    bilgi ve tecrübe ile ifadelere bakarak söyleyebileceklerim bu kadar. yine istediğiniz sonucu alamazsanız veritabanınız üzerinde sorgu analiz yapmanız/yaptırmanız gerekir.