MYSQL选择每一个“0”的3个结果;页面id”;


MYSQL select 3 results of each "page id"

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

我想从每个页面中获取前三个项目(按最高项目价格优先排序),该页面的累计最高价格优先排序。这完全超出了我的MYSQL能力,我正在寻找如何使其最高效的建议!:)谢谢

您可以用几种不同的方法来实现这一点。我要做的是运行一个查询,上面写着"让我所有页面按其项目的总和排序",然后在php中循环浏览它们,对于每个页面,做一个"让我获得当前页面的前3个项目"。

有道理吗?

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

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;
  • 我假设每个page_id都等于item_id,这就是它们链接在一起的方式。(如果没有,请纠正我。)
  • 我只想将第二个表称为"table2",并且我正在查找的item_id为"SOME_item_id"

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

在英语中,这句话的意思是:

从表2中选择item_id为this的所有内容,并按item_price按降序排列列表

这个SQL语句将返回每一次命中,但您只需要输出代码中的前三个。

我的直觉告诉我,要做到这一点,可能没有比在所有页面上的应用程序中执行for循环更快的方法了,为每个页面执行一个select item_price from item where page_id = ? order by item_price desc limit 3,并可能将结果粘贴到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中的每一行做大量的工作。许多其他RDBMS都有一个称为窗口函数的特性,它可以更优雅地完成上述操作。例如,如果你使用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;

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