Mysql Aynı Tabloda Farklı Koşullara Göre Toplam Kayıt Sayısını Bulmak

Farkındayım başlık çok uzun oldu ???? Ancak benim işime yaradığı gibi bir gün sizinde işinize yarayabilir. Şimdi örnek vermek gerekirse, yorumlar tablonuz olsun. Yorumların bazıları onaylı, bazıları onaysız olarak kayıt edilmiş. Ve siz toplam yorum sayısını, onaylı yorum sayısını ve onay bekleyen yorum sayısını bir sorguda almak istiyorsunuz. Mantıken nasıl yaparsınız? Ya subquery kullanırsınız ya da bunun yerine SUM() fonksiyonun kullanırsınız. Hemen bir örnek verelim.

Eğer count() fonksiyonunu kullanırsak;

SELECT count(yorum_id) toplam FROM yorumlar;

Sonuç;

+--------+
| toplam |
+--------+
|  2052  |
+--------+

Şimdi SUM() fonksiyonu ile birlikte şöyle bir kullanım yapacağız. Örneğin onay 1 ise onaylı yorumları, 0 ise onaysız yorumları saydıracağız.

SELECT
    count(yorum_id) toplam,
    SUM(onay = 1) onayli_yorumlar,
    SUM(onay = 0) onaysiz_yorumlar
FROM
    yorumlar

Sonuç;

+--------+-----------------+------------------+
| toplam | onayli_yorumlar | onaysiz_yorumlar |
+--------+-----------------+------------------+
|   2052 |               1 |             2051 |
+--------+-----------------+------------------+

Son olarak, eğer birden fazla tabloyu join ile bağladıktan sonra count işlemi yaptığınızda rakamlar saçmalıyorsa DISTINCT ile benzersizleri toplamak gerekir. Ama onun kullanımı biraz daha karışık, şöyle bir kullanım gerektiriyor;

SELECT
    count(yorum_id) toplam,
    REPLACE(SUM(onay = 1) * count(DISTINCT yorum_id) / count(*), '.0000', '') onayli_yorumlar,
    REPLACE(SUM(onay = 0) * count(DISTINCT yorum_id) / count(*), '.0000', '') onaysiz_yorumlar
FROM
    yorumlar
INNER JOIN
    ...

Bu yazım bu kadardı, bir gün böyle birşeye ihtiyaç olursa zaten takıldığınız noktada yorum yazarsınız. Kolay gelsin ????

MySQL 30 Günden Eski İçerikleri Silmek

30 günden eski içerikleri silmek büyük projelerde işimize yarayacaktır. Ben genelde öyle yapıyorum, çok önemli içerik depolanmıyorsa anlık olarak kullanıcıyı ilgilendiren içerikler ise belli aralıklarla bu sorguyu çalıştırıp 30 günden eski içerikleri veritabanınızda boşu boşuna yer kaplamaması için silebilirsiniz.

DELETE FROM tablo_adiniz
WHERE tarih_alani_adiniz < DATE_SUB(NOW(), INTERVAL 1 MONTH);

Kırmızı yere tablo adınızı, yeşil yere de tabloda tarihi tuttuğunuz alanın adını yazıp çalıştırmanız yeterli sorguyu.

İsterseniz 10 günlük, 15 günlük.. x günlük şeklinde de içerik silebilirsiniz.
O zamanda INTERVAL 1 MONTH yerine INTERVAL x DAY olacak.

Mesela 15 günlük içeriği silelim;

DELETE FROM tablo_adiniz
WHERE tarih_alani_adiniz < DATE_SUB(NOW(), INTERVAL 15 DAY);

Güncelleme: MySQL Event Scheduler (olay zamanlayıcısı) ile bu işlemi otomatikte yaptırabiliriz. Şu sorguyu çalıştırmamız yeterli;

SET GLOBAL event_scheduler = ON;

DELIMITER $$

CREATE EVENT clearLog
ON SCHEDULE EVERY ‘1’ MONTH
STARTS ‘2011-05-01 00:00:00′
DO
BEGIN
DELETE FROM tablo_adiniz WHERE tarih_alani_adiniz < DATE_SUB(NOW(), INTERVAL 1 MONTH);
END$$

DELIMITER ;