MySQL为每个不同的,获得一定数量的条目

时间:2013-05-01 14:56:16

标签: mysql

我现在有些困难,可以使用一些快速的MySQL帮助。

假设我有一个包含产品评论的表格,列product_idcustomerdate。 现在,对于每个不同的产品,我想获得3个第一次评论。 ORDER BY日期很简单,但我仍然坚持如何为每个不同的product_id准确地获取3个条目。因为它们都在同一个表中,所以INNER JOIN没有任何意义,GROUP BY也没有。 那么,有什么想法吗?

编辑:我已成功在SQLFiddle上使用此查询:

SELECT * FROM (
  SELECT customer, DATE, p_asin, @curTop := 
   CASE WHEN (
     @prevP_asin <> p_asin
   )
   THEN 1 
   ELSE @curTop +1
   END AS Top, @prevP_asin := p_asin
  FROM reviews2 r, (
    SELECT @curTop :=0
  ) A
 ORDER BY r.p_asin, r.date ) B
WHERE top <=3

但出于某种原因,当我尝试将它应用到我在PhpMyAdmin中的表时,对于新产品,Top的编号不会从1开始,而是全部计算在一起。 Fiddle和实际表格如何表现得如此不同?

3 个答案:

答案 0 :(得分:0)

在Oracle中,您可以使用rank(),但这在MySQL中不可用。我使用此页面了解如何执行此操作:rank over in mysql

此外,它位于SQLFiddle

SELECT * FROM (
SELECT 
  product_id,
  customer,
  @curRank := case when (@prevProductID <> product_id)
               then  1 else   @curRank + 1 
             end as Rnk,
  @prevProductID := product_id
FROM
   products p, (
     SELECT @curRank := 0
   ) r
ORDER BY
  P.product_id, P.date
) A
  WHERE Rnk <= 3

答案 1 :(得分:0)

以下内容仅在我们可以假定日期值对于给定产品是唯一的时才有效。如果不是这样,那么您需要在“p1.date&lt; p.date”之后的where语句中添加一个唯一值,以便每行获得一个唯一的排名。

SQLFiddle here

SELECT * FROM (
    SELECT 
      product_id,
      customer, (
      select count(*) as cnt from products p1 
          where p1.product_id = p.product_id and
                p1.date < p.date
        ) rnk
    FROM  
      products P
    ORDER BY
      P.product_id, P.date
    ) A
  WHERE rnk < 3

答案 2 :(得分:0)

我知道问这个问题已经有一段时间了,但是现在SQL 8.0已经发布了一段时间,我想我可以补充一点,我们可以通过键使用ROW_NUMBER()来分区列(OP的问题中的product_id。)+通过另一列(OP的问题中的日期)订购

在坚果壳中,我们要做的是:

  1. 加入有问题的表
  2. 按键列(product_id)和所需的其他任何列进行排序。
  3. 为每条记录赋予行号-将键列的每个不同值的计数重置为[我们遇到的每个新product_id]
  4. 将上述步骤中的行号用作WHERE条件,以选择前n行(例如WHERE row_number <= 3,以获取键列中每个不同值的前3行)

示例:

SELECT FULL_TABLE.*
FROM (
         SELECT P.*,
                PD.*,
                ROW_NUMBER() over (
                    PARTITION BY P.id
                    ORDER BY P.date
                    ) AS row_num
         FROM Products AS P
                  LEFT JOIN ProductDetails AS PD on P.id = PD.productId
         ORDER BY P.id, row_num
     ) AS FULL_TABLE
WHERE row_num <= 3;