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 ?
MySQL ile Multiple Join Count ?
8
●3.123
- 27-06-2018, 01:39:23Bana bu tabloların sql halini gönderirseniz sorgu cümlesini yazıp gönderirim size
- 27-06-2018, 03:10:00Sistemin patladığı yer multiple join oluyor 6 tane daha join yapıyor çünkü tablo :/ ben basite indirgeyerek anlattım;ahmethekim14 adlı üyeden alıntı: mesajı görüntüle
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:27Kimlik 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:16anlamadığım şey şu count yaparken işlem görmezken sum u nasıl kabul etti ?ztk adlı üyeden alıntı: mesajı görüntüle
- 27-06-2018, 15:03:32Siz 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.Burti adlı üyeden alıntı: mesajı görüntüle
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:41merhaba,ztk adlı üyeden alıntı: mesajı görüntüle
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:40ztk adlı üyeden alıntı: mesajı görüntüleztk adlı üyeden alıntı: mesajı görüntüleCoreDeluxe 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
- 28-06-2018, 08:29:56ben 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.Burti adlı üyeden alıntı: mesajı görüntüle
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.

