0

我正在开发一个拍卖网络应用程序。现在我有一个带有投标的表格,我想从这个表格中选择每次拍卖的最后 10 个投标。

现在我知道我可以通过以下方式获得最后的出价:

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

现在我已经读到为 GROUP BY 结果设置一个数量并不是一件容易的事,实际上我没有找到简单的解决方案,如果有的话我想听听。

但是我想出了一些解决方案来解决这个问题,但我不确定我是否做得很好。

选择

第一件事是创建一个新表,命名为 bids_history。在此表中,我存储了最后一项的字符串。

例子:

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

我还必须存储名称和时间,因为我没有找到简单的方法来获取bid_id(20,25,40) 中使用的字符串,并且只在连接中使用它。这样我就可以加入拍卖ID,我有最新的结果。

现在,当有新的出价时,这些是步骤:

  • 在出价中插入出价 获取最后插入的 ID
  • 获取此拍卖产品的 bids_history 字符串
    • 爆炸字符串
    • 插入新值
    • 检查是否有超过 3 个
    • 内爆数组,然后再次插入字符串

在我看来,这一切都不是一个很好的解决方案。我真的不知道该走哪条路。请记住,这是一个有很多出价的网站,每个拍卖品最多可以出价 15.000 个。也许因为这个数量是 GROUPING 和 ORDERING 不是一个好方法。如果我错了,请纠正我。

拍卖结束后,我会清理出价表,删除所有出价,并将它们存储在单独的表中。

有人可以帮我解决这个问题!

如果你去过,谢谢阅读..

编辑

我使用的表是:

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)

作为查询的结果,我想要什么:

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

所以这是每次拍卖的最新出价,按数字选择,3 或 10

4

5 回答 5

1

使用用户变量控制流,我最终得到了(如果你想要十次拍卖,只需替换为)<=3<=10

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
于 2010-03-03T12:36:42.787 回答
0

编辑:这是错误的:-)

您将需要使用子查询:

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

因此,子查询执行从出价到自身的左连接,将每条记录与具有相同拍卖 ID 和创建日期晚于其创建日期的所有记录配对。对于最近的记录,不会有其他记录具有更大的创建日期,因此该记录不会包含在联接中,但由于我们使用左联接,它将被包括在内,所有 bids2 字段都为空,因此WHERE bid2.id IS NULL声明。

因此,子查询每次拍卖有一行,包含最近出价的数据。然后只需使用 orderby 和 limit 选择前十名。

如果您的数据库引擎不支持子查询,您也可以使用视图。

于 2010-03-02T14:28:57.550 回答
0

好的,这个应该可以工作:

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

因此,像以前一样,将加入出价与自身分开,这样我们就可以将每个出价与所有其他出价进行比较。然后,首先按拍卖分组(我们希望每次拍卖的最后十个出价),然后按创建分组。因为左连接将每个出价与所有先前的出价配对,所以我们可以计算每个组的 bids2.created 的数量,这将为我们提供在该出价之前发生的出价数量。如果此计数 < 9(因为第一个将具有 count == 0,它是零索引)它是最近的十个投标之一,我们要选择它。

于 2010-03-02T14:51:10.547 回答
0

要选择给定拍卖的最后10出价,只需创建一个规范化bids表(每个出价 1 条记录)并发出以下查询:

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

要为多次拍卖选择最后10出价,请使用以下命令:

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)

为此创建一个复合索引以bids (auction, created, id)使其快速工作。

于 2010-03-02T14:08:21.273 回答
0

为什么要在一个查询中执行此操作?

$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";
// ...

您显然应该处理例如$auctions为空的情况,但我认为这应该可行。

于 2010-03-02T14:41:36.417 回答