使用mySQL为每个类别选择两个不同的随机条目

时间:2012-09-01 17:31:51

标签: mysql group-by left-join

我有一张看起来像这样的表:

table: Q
---------------------------
|question| scope |  type  |
---------------------------
|  this  |   A   |   1    |
|  that  |   A   |   1    |
|  them  |   A   |   1    |
---------------------------
|  this  |   A   |   2    |
|  that  |   A   |   2    |
|  them  |   A   |   2    |
---------------------------
|  this  |   B   |   1    |
|  that  |   B   |   1    |
|  them  |   B   |   1    |
---------------------------

我需要一个范围,我需要从每种类型中提取两个条目。如果范围是A,则可能的解决方案可能是:

---------------------------
|  this  |   A   |   1    |
|  them  |   A   |   1    |
---------------------------
|  that  |   A   |   2    |
|  this  |   A   |   2    |
---------------------------

我目前正在使用以下SQL语句:

SELECT tmp.question, tmp.type, tmp.scope
FROM Q
LEFT JOIN (
SELECT * FROM Q ORDER BY RAND( )
)tmp ON ( Q.type = tmp.type AND tmp.scope = 'A' ) 
GROUP BY tmp.type
ORDER BY Q.type

然而,这只会返回每个类型一个条目,并且由于某种原因会返回NULL行。
因此,我的问题是如何优化语句以返回两行并消除NULL行?

2 个答案:

答案 0 :(得分:2)

您可以将等级从2更改为您希望为每个类别获得的任何内容。

http://www.sqlfiddle.com/#!2/f3946/86

试试这个:

  SELECT x.question,
       x.scope,
       x.type
  FROM (

    SELECT bp.question, bp.scope, bp.type, 
    CASE WHEN bp.type = @type 
         THEN @rownum := @rownum + 1
         ELSE @rownum := 1
         END AS rank,
    @type := bp.type
FROM (select * from Q order by rand()) bp
JOIN (SELECT @rownum := 0, @type := NULL) r
WHERE bp.scope = 'A'
ORDER BY type
    ) x
 WHERE x.rank <= 2
order by x.type

注意:我使用旧答案并进行了随机化改进。 我得到帮助的老答案是: Select N records for each category and order by X

答案 1 :(得分:0)

<强> SqlFiddle

(
  SELECT question, scope, type FROM Q
  WHERE  scope = 'A' AND type = 1
  ORDER BY RAND() LIMIT 2
)
UNION
(
  SELECT question, scope, type FROM Q
  WHERE  scope = 'A' AND type = 2
  ORDER BY RAND() LIMIT 2
)