MYSQL选择每个“页面ID”的3个结果

时间:2012-03-25 02:41:47

标签: php mysql greatest-n-per-group

我有两个表...第一个是带有(page_id,page_title)行的页面列表。第二个是这些页面上的项目列表,每个页面都有一个价格(item_id,page_id,item_title,item_price)。

我想抓住每个页面中的前三项(按照最高的item_price排序),首先订购累积最高价格的页面。这超出了我的MYSQL能力,我正在寻找有关如何使其最有效的建议! :)谢谢!

3 个答案:

答案 0 :(得分:0)

你可以用几种不同的方式做到这一点。我要做的是运行一个查询,说“让我的所有页面按其项目的总和排序”,然后在php中循环浏览它们,并为每一个执行“获取当前页面的前三项”

有意义吗?

查询一个(未经测试,写在我的手机上):

SELECT p.page_name, (SELECT SUM(item_price) FROM items WHERE page_id = p.page_id) AS cumulative_price FROM pages p ORDER BY cumulative_price DESC;

查询两个(也未经测试)循环查询结果:

SELECT * FROM items WHERE page_id = '$currentPageId' ORDER BY item_price DESC LIMIT 3;

答案 1 :(得分:0)

  • 我假设每个page_id都等于item_id,这就是它们如何链接在一起。 (如果没有,请纠正我。)
  • 我只是打算调用第二个表“table2”和item_id我正在查找“SOME_ITEM_ID”

    SELECT * FROM `table2` WHERE `item_id` = 'SOME_ITEM_ID' ORDER BY `item_price` DESC;
    

用英语说的是:

从table2中选择item_id为 的所有内容,然后按item_price按降序排列列表

此SQL语句将返回每次匹配,但您只需输出代码中的前三个。

答案 2 :(得分:0)

我的直觉告诉我,可能没有更快的方式来做到这一点,而不是在应用程序中对所有页面执行for循环,为每个页面做一点select item_price from item where page_id = ? order by item_price desc limit 3 paqe,并且可能会将结果粘贴到memcached之类的内容中,这样您就不会对数据库造成过多的负担。

但我喜欢挑战,所以无论如何我都会尝试。

SELECT p1.*, i1.*,
 (SELECT count(*)
  FROM items i2
  WHERE i1.item_price < i2.item_price
  AND p1.page_id = i2.page_id) price_rank,
FROM pages p1 
LEFT OUTER JOIN items i1 
 ON p1.page_id = i1.page_id
WHERE price_rank < 3;

奇怪的子选择可能会为items中的每一行做很多工作。许多其他RDBMses都有一个称为窗口函数的功能,它可以更加优雅地完成上述操作。例如,如果你使用PostgreSQL,你可以写:

SELECT p1.*, i1.*, 
    RANK(i1.item_price) 
    OVER (PARTITION BY p1.page_id
          ORDER BY i1.item_price DESC) price_rank 
FROM pages p1 
LEFT OUTER JOIN items i1 
 ON p1.page_id = i1.page_id
WHERE price_rank <= 3;

规划人员会安排按顺序访问行,从而使排名正常发生。