Bir veritabanında yorumu göre sıralama - Nereye Bu SQL koymak için?

5 Cevap php

Tamam - Ben noktasına düz alırsınız - burada söz PHP kodu:

<h2>Highest Rated:</h2>

    <?php 

        // Our query base               
        $query = $this->db->query("SELECT * FROM code ORDER BY rating DESC");

        foreach($query->result() as $row) {
    ?>  
        <h3><?php echo $row->title." ID: ";echo $row->id; ?></h3>
            <p class="author"><?php  $query2 = $this->db->query("SELECT email FROM users WHERE id = ".$row->author);
echo $query2->row('email');?></p>
            <?php   echo ($this->bbcode->Parse($row->code)); ?>

        <?php } ?>

Biraz dağınık Üzgünüm, hala bir taslak. Her neyse, ben bir Ratings sistemi kullanmak yollarını araştırdı - Eğer oylaması DESC kod SİPARİŞ SELECT * görebileceğiniz gibi daha önce ben bir tek 'rating' alan vardı. Ancak hızlı bir şekilde bu gibi ortalamalar hesaplama mümkün değildi fark, bu yüzden beş yeni sütunlar yarattı - Değerlendirme1, rating2, Değerlendirme3, Değerlendirme4, Değerlendirme5. 5 kullanıcı şey reytinge Yani 4 yıldız, Değerlendirme4 5 diyor ... bu mantıklı mı? Her ratingx sütun oylaması verildi sayısını sayar.

Neyse: Bu SQL deyimi var:

SELECT id, (ifnull(rating1,0) + ifnull(rating2,0) + ifnull(rating3,0) + ifnull(rating4,0) + ifnull(rating5,0)) / ((rating1 IS NOT NULL) + (rating2 IS NOT NULL) + (rating3 IS NOT NULL) + (rating4 IS NOT NULL) + (rating5 IS NOT NULL)) AS average FROM code

Yine dağınık, ama hey. Şimdi ne bilmek gerekir nasıl benim komut dosyası içine SQL deyimini dahil edebilirsiniz nedir? İdeal genel sorgu '(that really long query i just stated) DESC kod SİPARİŞ SELECT *' düşünürdüm ama oldukça çalışma ... Ben bunu nasıl yaparım bunu göremiyor? Sorgu, bir değişken böyle bir şey sonucu depolamak?

Hiçbir anlamda dileriz yaparsa! Ama gerçekten yardım ederiz :)

Kriko

5 Cevap

Tamamen silbaştan gitmek gerekir.

<?php
$query = $this->db->query("SELECT * FROM code ORDER BY rating DESC");
foreach($query->result() as $row) {
    $this->db->query("SELECT email FROM users WHERE id = ".$row->author;
}

Anytime kodunuzda bu bakın, hemen ne yaptığınızı durdurmak. Bunun için ne Katıldı. Sen bir sorgunun sonuçları üzerinde döngü istiyorum ve bu döngü içinde birden sorguları hemen hemen hiç.

SELECT code.*, users.email 
FROM code
JOIN users ON users.id = code.author
ORDER BY rating DESC

Bu sorgu N +1 sorgu sorun çıkarmadan, bir tek resultset'de tüm bu verileri çekecek.

Bazı soru temizlemek ve yapmak için çalışıyoruz ne açıklamak kadar ben senin sorunun kalanını ele değilim.

Eğer tekrar tabloları değiştirmek istiyorsanız, burada benim öneri:

neden iki sütun tutmayın: RatingTotal ve derecelendirme sayısı, bu biri tarafından derecelendirme sayısı artacaktır fiyatları her kullanıcı, ve onlar (5,4,4.2, vb) oy ne olursa olsun RatingTotal eklenir. Yapabildin sonra RatingTotal / derecelendirme sayısı BY sadece SİPARİŞ

Ayrıca, ben kullanıcıların her madde puan depolamak umut, bu yüzden birden çok kez oy yok! ve ortalama kendi yolumuzu salıncak.

Birincisi, uygulama yazma ağır olup olmadığına karar ediyorum ya da okuma-ağır. Çok daha fazla yazma okuma varsa, o zaman üzerinde (örneğin, bu komut dosyası gibi) okur musun işin miktarını en aza indirmek istiyoruz. Varsayımına salt ağır oluyor ki, en webapps olduğundan, ben ayrı bir sütuna kombine ortalama sürdürmek ve bir kullanıcı yeni bir değerlendirme ekler zaman bu hesaplamaya öneririm.

Diğer seçenekler şunlardır:

  • Hesaplanan sütun adı 'ortalama' tarafından sipariş sahipsiniz. SQL Server, bu destekler. . mysql konusunda emin değil.
  • Bir görünümünü kullanın. Sizin için ortalama hesaplama yapar ve bunu karşı sorgulayabilirsiniz Baz masada bir görünüm oluşturabilirsiniz.

Ayrıca, soruyla ilgisi olmayan, kendi döngü içinde her kullanıcı için ayrı bir sorgu yapmıyoruz. Orijinal sorguda kod tablosuna kullanıcıların tablo katılın.

Sen Seç bölümünde bunu içermelidir:

SELECT *, (if ....) AS average FROM ... ORDER BY average

Edit: sizin IFNULL getChild çalıştığını varsayarak ...

Ayrıca her kullanıcı için tekrar veritabanı sorgulama önlemek için katılır içine bakmak isteyebilirsiniz; Eğer 1 select deyiminde her şeyi yapabilirsiniz.

Bunun dışında ben de sadece bir ortalama ve toplam oyların sayısını gerektiğini söyleyebilirim itibaren, bu size ihtiyacınız olan tüm bilgileri vermelidir.

Sütunlar derece ve times_rated sahip olmak ve sadece böyle bir şey yapacağını (yıldız daha ağır yazmak o ağır okumuş söyledi gibi) bazı mükemmel fikirler, ama ben en iyi şekilde düşünüyorum:

new_rating = ((times_rated * rating) + current_rating) / (times_rated + 1)

kişi küçük yıldızlı tıkladığında oylaması uygulanan olmak current_rating. Akım değerine sahip bir ortalama Bu sadece ağırlıkları geçerli kullanıcının değerlendirmesi.