MYSQL从每个类别中选择2个随机行

时间:2015-03-04 15:12:19

标签: mysql sql select

我有一个包含这样的列的mysql表:

`qid`, `category`, `question`, `choice_1`, `choice_2`, `choice_3`, `answer`

在此表中,我有2000个数据,有7个不同的“类别”。我想从这个表中获取15个随机行,每个类别的数字相同。由于我有7个类别,因此不可能从每个类别获得相同数量的行。在这种情况下,我可以从一个类别获得3。如何通过一个查询实现这一目标?

我想从每个类别中获取2行。然后我将总共有14行,然后我可以从表中获得1个随机行并合并记录。请给我看一个示例查询。谢谢。这是我的实际表格结构:

CREATE TABLE IF NOT EXISTS `difi_questions` (
  `qid` smallint(6) NOT NULL AUTO_INCREMENT,
  `category` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `question` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `choice_1` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `choice_2` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `choice_3` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `answer` enum('1','2','3') COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`qid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1959 ;

2 个答案:

答案 0 :(得分:4)

如您所述,每个类别只需获取2个,最后一个随机获取一个。它不是一个查询,而是一个结果集,可能就是您所需要的:

SELECT * FROM (SELECT * FROM questions WHERE category= 1 ORDER BY rand() limit 0,2) as t1
UNION
SELECT * FROM (SELECT * FROM questions WHERE category= 2 ORDER BY rand() limit 0,2) as t2
UNION 
SELECT * FROM (SELECT * FROM questions WHERE category= 3 ORDER BY rand() limit 0,2) as t3
UNION
...

(嵌套的Select允许您按类别按rand()排序) 到目前为止没什么特别的 - 每个类别2个随机问题。

现在棘手的部分是添加第15个元素 WITHOUT 选择你已经拥有的任何元素。

要通过“一次”通话实现此目的,您可以执行以下操作:

  • 选择上面选择的14个问题的子集。
  • 将此与来自数据库的未分类的随机排序事物联合起来。 (限制0,15)
  • 从此结果中选择全部,限制为0,15。

  • 如果已经选择了LAST子查询的前14个元素 - 它们将因UNION而被删除,并保证独立的第15个元素。

  • 如果最终的内部查询也选择了15个不同的问题,那么外部限制0,15只会将第一个问题带入结果中。

类似的东西:

SELECT * FROM (
    SELECT * FROM (SELECT * FROM questions WHERE category= 1 ORDER BY rand() limit 0,2) as t1
    UNION
    SELECT * FROM (SELECT * FROM questions WHERE category= 2 ORDER BY rand() limit 0,2) as t2
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 3 ORDER BY rand() limit 0,2) as t3
    UNION
    ...
    UNION
    SELECT * FROM (SELECT * FROM questions ORDER BY rand() LIMIT 0,15) as t8
) AS tx LIMIT 0,15

这有点难看,但应该完全按照您的需要做:从每个类别中随机提出两个问题,最后是一个尚未从任何类别中选择过的随机问题。任何时候共有15个问题。

(Sidenode:您可以运行第二个查询,在确定7个类别的14个问题后,使用NOT IN ()拒绝已选择的问题。)

编辑:不幸的是,SQL Fiddle目前无法正常工作。这是一些小提琴代码:

CREATE TABLE questions (id int(10), category int(10), question varchar(20));

INSERT INTO questions (id, category, question)VALUES(1,1,"Q1");
INSERT INTO questions (id, category, question)VALUES(2,1,"Q2");
INSERT INTO questions (id, category, question)VALUES(3,1,"Q3");
INSERT INTO questions (id, category, question)VALUES(4,2,"Q4");
INSERT INTO questions (id, category, question)VALUES(5,2,"Q5");
INSERT INTO questions (id, category, question)VALUES(6,2,"Q6");
INSERT INTO questions (id, category, question)VALUES(7,3,"Q7");
INSERT INTO questions (id, category, question)VALUES(8,3,"Q8");
INSERT INTO questions (id, category, question)VALUES(9,3,"Q9");
INSERT INTO questions (id, category, question)VALUES(10,4,"Q10");
INSERT INTO questions (id, category, question)VALUES(11,4,"Q11");
INSERT INTO questions (id, category, question)VALUES(12,4,"Q12");
INSERT INTO questions (id, category, question)VALUES(13,5,"Q13");
INSERT INTO questions (id, category, question)VALUES(14,5,"Q14");
INSERT INTO questions (id, category, question)VALUES(15,5,"Q15");
INSERT INTO questions (id, category, question)VALUES(16,6,"Q16");
INSERT INTO questions (id, category, question)VALUES(17,6,"Q17");
INSERT INTO questions (id, category, question)VALUES(18,6,"Q18");
INSERT INTO questions (id, category, question)VALUES(19,7,"Q19");
INSERT INTO questions (id, category, question)VALUES(20,7,"Q20");
INSERT INTO questions (id, category, question)VALUES(21,7,"Q21");

查询

SELECT * FROM (
    SELECT * FROM (SELECT * FROM questions WHERE category= 1 ORDER BY rand() limit 0,2) as t1
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 2 ORDER BY rand() limit 0,2) as t2
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 3 ORDER BY rand() limit 0,2) as t3
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 4 ORDER BY rand() limit 0,2) as t4
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 5 ORDER BY rand() limit 0,2) as t5
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 6 ORDER BY rand() limit 0,2) as t6
    UNION 
    SELECT * FROM (SELECT * FROM questions WHERE category= 7 ORDER BY rand() limit 0,2) as t7
    UNION 
    SELECT * FROM (SELECT * FROM questions ORDER BY rand() LIMIT 0,15) as t8
) AS tx LIMIT 0,15

示例数据每个类型包含3个问题,导致第15个问题(最后一行)始终是从类别中剩余的问题。

答案 1 :(得分:0)

试试这个:)

CREATE TABLE IF NOT EXISTS `difi_questions_temp` (
  `qid` smallint(6) NOT NULL ,
  `category` varchar(255)  NOT NULL
);

INSERT INTO difi_questions_temp
select qid, category from (
SELECT qid, category
FROM difi_questions 
order by rand()) as x
GROUP BY category;


INSERT INTO difi_questions_temp
select qid, category from (
SELECT qid, category
FROM difi_questions 
where qid not in (select qid from difi_questions_temp)
order by rand()) as x
GROUP BY category;

insert into difi_questions_temp 
select qid, category from difi_questions
where qid not in (select qid from difi_questions_temp)
order by rand()
limit 1 ;

/*select qid,  category from difi_questions_temp order by category; */
select * from difi_questions where qid in ( select qid from difi_questions_temp);
drop table difi_questions_temp;