Grubun başına sonuç BY birden GROUP alın, ya da ayrı ayrı birleştirilmiş tablo kullanmak

5 Cevap php

Ben bir açık artırma web uygulaması üzerinde çalışıyorum. Şimdi ben teklif bir tablo var ve bu tablodan ben açık arttırmada son 10 tekliflerini seçmek istiyorum.

Şimdi ben gibi bir şey kullanarak son teklif alabilirsiniz biliyorum:

SELECT bids.id FROM bids WHERE * GROUP BY bids.id ORDER BY bids.created

Şimdi ben duymak isterim varsa sonuçlarının GROUP BY için bir miktar ayarı, aslında hiç de kolay bir çözüm bulduk, yapmak kolay bir şey olmadığını okudum.

Ama bu sorunu çözmek için bazı çözümler ile geldi, ama ben de bunu yapıyorum emin değilim.

Alternative

Ilk şey bu bids_history çağırarak, yeni bir tablo yaratıyor. Bu tabloda i geçen öğelerin bir dizesini depolamak.

Örnek:

bids_history
================================================================
auction_id   bid_id     bidders               times
    1        20,25,40   user1,user2,user1     time1,time2,time3

I have to store the names and the times too, because I have found no easy way of taking the string used in bid_id(20,25,40), and just using this in a join. This way i can just just join on auction id, and i have the latest result.

Şimdi yeni bir teklif var yerleştirildiğinde, bu adımlar şunlardır:

  • Teklifleri lastinserteid almak içine teklifi eklemek
  • get the bids_history string for this auction product
    • dize patlayabilir
    • yeni değerler eklemek
    • 3'ten fazla olup olmadığını kontrol
    • dizi implode ve tekrar dize eklemek

This all seems to me not a very well solution. I really don't know which way to go. Please keep in mind this is a website with a lot of bidding's, they can g up to 15.000 bidding's per auction item. Maybe because of this amount is GROUPING and ORDERING not a good way to go. Please correct me if I am wrong.

I tüm teklifleri kaldırarak, tekliflerin tabloyu temizlemek, ve ayrı bir tabloda saklayabilirsiniz yapmak üzerine ihale sonra.

Birisi bana bu sorunu çözmek yardım edebilir misiniz!

Ve eğer sen-si, okuma için teşekkürler ..

DÜZENLEME

I kullanma tablolar şunlardır:

bids
======================
id      (prim_key)
aid     (auction id)
uid     (user id)
cbid    (current bid)
created (time created)
======================

auction_products
====================
id        (prim_key)
pid       (product id)
closetime (time the auction closses)

I sorgu sonucu ne istiyorsun:

result
===============================================
auction_products.id   bids.uid   bids.created
2                        6         time1
2                        8         time2
2                        10        time3
5                        3         time1
5                        4         time2
5                        9         time3
7                        3         time1
7                        2         time2
7                        1         time3

Yani bu sayı, 3 ya da 10 ile seçmek için, açık arttırma başına son teklifleri olduğunu

5 Cevap

user variable kullanılarak, ve control flow, ben o ile sona (eğer on ihaleleri istiyorsanız sadece <=10 ile <=3 olarak değiştirin):

SELECT a.*
FROM
 (SELECT aid, uid, created FROM bids ORDER BY aid, created DESC) a,
 (SELECT @prev:=-1, @count:=1) b
WHERE
 CASE WHEN @prev<>a.aid THEN
   CASE WHEN @prev:=a.aid THEN
    @count:=1
   END
 ELSE
   @count:=@count+1
 END <= 3

Neden bir sorguda bunu?

$sql = "SELECT id FROM auctions ORDER BY created DESC LIMIT 10";
$auctions = array();

while($row = mysql_fetch_assoc(mysql_query($sql)))
  $auctions[] = $row['id'];

$auctions = implode(', ', $auctions);
$sql = "SELECT id FROM bids WHERE auction_id IN ($auctions) ORDER BY created LIMIT 10";
// ...

Açıktır ki burada, örneğin davayı ele almalıdır $auctions boş, ama ben bu çalışması gerektiğini düşünüyorum.

EDIT: Bu yanlış olduğunu :-)

Bir alt sorgu kullanmanız gerekir:

SELECT bids1.id
FROM ( SELECT *
       FROM bids AS bids1 LEFT JOIN
            bids AS bids2 ON bids1.created < bids2.created
                          AND bids1.AuctionId = bids2.AuctionId
       WHERE bid2.id IS NULL)
ORDER BY bids.created DESC
LIMIT 10

Yani sorgu aynı auctionId ve kendi oluşturduğunuz tarihinden sonra oluşturulmuş bir tarih olan tüm kayıtları ile her kaydı eşleştirme, bir sol kendisine tekliflerinden katılmak gerçekleştirir. En son kayıt için, daha büyük bir oluşturulma tarihi ile başka bir rekor olacak ve böylece rekor katılmak dahil olmaz, ama biz bir Sol katılmak kullanmak beri, tüm bids2 alanlar boş olmak, dahil edilecek dolayısıyla WHERE bid2.id IS NULL deyimi.

Yani alt sorgu en son teklifinden verileri contianing, açık arttırma başına bir satır vardır. Sonra sadece OrderBy ve limitini kullanarak ilk on kapalı seçin.

Veritabanı motoru alt sorgular desteklemiyorsa, sadece de bir görünümünü kullanabilirsiniz.

Tamam, bu bir çalışması gerekir:

SELECT bids1.id
FROM bids AS bids1 LEFT JOIN
     bids AS bids2 ON bids1.created < bids2.created
                   AND bids1.AuctionId = bids2.AuctionId
GROUP BY bids1.auctionId, bids1.created
HAVING COUNT(bids2.created) < 9

Yani, eskisi gibi, bu yüzden tüm diğerleri ile her teklifi karşılaştırabilirsiniz kendisi ile teklifleri katılmak bıraktı. Ardından grup ilk açık artırma tarafından oluşturulan daha sonra da (biz açık artırma başına son on teklifleri istiyorum) ve. Sol önceki tüm teklif çiftleri her teklifinizi katılmak çünkü, biz o zaman bize bu teklife önce meydana gelen tekliflerin numarası verecektir grup başına bids2.created sayısını sayabilirsiniz. Bu sayısı ise < 9 o on en son tekliflerin biridir (ilk sayım == 0 olacak, çünkü sıfır endeksli olduğu), ve bunu seçmek istiyorum.

, Belirli bir açık arttırma son 10 tekliflerini seçmek sadece bir normalize bids tablo (teklif başına 1 kayıt) oluşturmak ve bu sorguyu vermek için:

SELECT  bids.id
FROM    bids
WHERE   auction = ?
ORDER BY
        bids.created DESC
LIMIT 10

Birden fazla ihale başına geçen 10 tekliflerini seçmek için, bu kullanın:

SELECT  bo.*
FROM    (
        SELECT  a.id,
                COALESCE(
                (
                SELECT  bi.created
                FROM    bids bi
                WHERE   bi.auction = a.id
                ORDER BY
                        bi.auction DESC, bi.created DESC, bi.id DESC
                LIMIT 1 OFFSET 9
                ), '01.01.1900'
                ) AS mcreated
                COALESCE(
                (
                SELECT  bi.id
                FROM    bids bi
                WHERE   bi.auction = a.id
                ORDER BY
                        bi.auction DESC, bi.created DESC, bi.id DESC
                LIMIT 1 OFFSET 9
                ), 0)
                AS mid
        FROM    auctions a
        ) q
JOIN    bids bo
ON      bo.auction >= q.auction
        AND bo.auction <= q.auction
        AND (bo.created, bo.id) >= (q.mcreated, q.mid)

Bu hızlı çalışması için bids (auction, created, id) üzerine bir bileşik dizin oluşturun.