我有两张桌子。
表1有两列:brand
和review_counter
。
表2还有两列:brand
和review
。
每个品牌都有几条评论。有没有办法在SQL中随机选择每个品牌大约10%的评论,而不使用“top n”命令?
例如对于'Sony'有2,005条评论,我需要选择10%,200条评论。
提前谢谢。
答案 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))
您可以使用以下解决方案之一来提高效率: -
答案 1 :(得分:1)
RAND()
生成介于0和1之间的随机值。为什么不尝试这个?
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