如何在SQL中选择具有特定条件的n%随机行?

时间:2014-06-25 08:47:33

标签: mysql sql

我有两张桌子。

表1有两列:brandreview_counter

表2还有两列:brandreview

每个品牌都有几条评论。有没有办法在SQL中随机选择每个品牌大约10%的评论,而不使用“top n”命令?

例如对于'Sony'有2,005条评论,我需要选择10%,200条评论。

提前谢谢。

2 个答案:

答案 0 :(得分:2)

使用用户计数器的可能方法。与上述类似的解决方案相比,这可能会为每个品牌带来更准确的10%的评论,但也可能更慢(两种解决方案都不会很快,因为两者都依赖于在每一行上使用RAND()表)。

这将获得所有行,按品牌排序,然后按兰德()排序。它将其用作子查询并添加序列号,为每个品牌的第一条记录重置为1。然后,这又被用作查询的来源,该查询消除了生成的序列号是< =该品牌的评论的十分之一的记录。

SELECT sub1.brand, sub1.review
FROM
(
    SELECT sub0.brand, sub0.reviews_wanted, sub0.review, @cnt:=IF(@brand = brand, @cnt+1, 1) AS cnt, @brand := brand
    FROM
    (
        SELECT Table1.brand, (Table1.review_counter * 0.1) AS reviews_wanted, Table2.review
        FROM Table1 
        INNER JOIN Table2 
        ON Table1.brand = Table2.brand
        ORDER BY Table1.brand, RAND()
    ) sub0
    CROSS JOIN (SELECT @cnt:=0, @brand:='') sub2
) sub1
WHERE cnt <= sub1.reviews_wanted

EDIT。

这可能会提高内存效率(虽然可能更慢)。

这是一个子查询,以随机顺序获取品牌的所有评论的唯一ID,以及该品牌评论数量的十分之一。然后,它使用带有SUBSTRING_INDEX的计数来获取第一个随机10%的ID,并使用FIND_IN_SET和评论表将其连接起来。

SELECT sub0.brand, Table2.review
FROM
(
    SELECT Table1.brand, CEIL(Table1.review_counter * 0.1) AS reviews_wanted, GROUP_CONCAT(Table2.id ORDER BY RAND()) AS id
    FROM Table1 
    INNER JOIN Table2 
    ON Table1.brand = Table2.brand
    GROUP BY Table1.brand, reviews_wanted
) sub0
INNER JOIN Table2
ON FIND_IN_SET(Table2.id, SUBSTRING_INDEX(sub0.id, ',', reviews_wanted))

您可以使用以下解决方案之一来提高效率: -

How can i optimize MySQL's ORDER BY RAND() function?

答案 1 :(得分:1)

RAND()生成介于0和1之间的随机值。为什么不尝试这个?

UPDATED2

SELECT review
FROM 
( 
    SELECT review, (review_counter * RAND()) / review_counter AS rand
    FROM Table1 INNER JOIN Table2 ON Table1.brand = Table2.brand
) t
WHERE rand < 0.1