2010-06-24 49 views
0

这里是我当前的查询:需要知道,如果这是可能的SQL如果是的话,该怎么办呢

SELECT questions.question, questions_headings.title FROM questions JOIN questions_headings ON questions.heading=questions_headings.id WHERE questions.heading IN (1,2,3) ORDER BY RANDOM() LIMIT 10 

基本上,该数据库包含各种标题问题。例如:

questions_headings: 

+----+-------+ 
| id | title | 
+----+-------+ 
| 0 | blah1 | 
+----+-------+ 
| 1 | lol1 | 
+----+-------+ 
| 2 | etc1 | 
+----+-------+ 

questions: 

+----+---------+----------+ 
| id | heading | question | 
+----+---------+----------+ 
| 0 | 1  | howdoi | 
+----+---------+----------+ 
| 1 | 0  | blahques | 
+----+---------+----------+ 
| 2 | 1  | herro | 
+----+---------+----------+ 

我的查询所做的是从给定标题中随机选择X个问题并将其显示给用户。

目前,如果你想要10个随机问题(限制10),它会给你10个随机问题跨所有ID。正常,对吧?但我不想要这个。

我需要查询的是,抽出10个随机问题分布在给定的ID。那样的话,我不会以一个标题的9个问题和另一个问题的1个问题结束。

希望这是有道理的......

是否有可能只用SQL做到这一点?

+0

等分布不是随机的。 – Naktibalda 2010-06-24 08:28:06

+0

我知道这个问题可能只是一个例子,但在我看来,这两个表都有1对1的关系,因此将它们拆分成不同的表是不必要的。 – 2010-06-24 09:53:14

+1

这是一对多的关系。一个标题可以有n个问题。 – 2010-06-24 10:33:14

回答

0

如果在创建查询时知道的标题,你可以这样做以下:

SELECT * FROM (
    SELECT questions.question, questions_headings.title FROM questions JOIN questions_headings ON questions.heading=questions_headings.id WHERE questions.heading = 1 ORDER BY RANDOM() LIMIT 3 
    UNION 
    SELECT questions.question, questions_headings.title FROM questions JOIN questions_headings ON questions.heading=questions_headings.id WHERE questions.heading = 2 ORDER BY RANDOM() LIMIT 3 
    UNION 
    SELECT questions.question, questions_headings.title FROM questions JOIN questions_headings ON questions.heading=questions_headings.id WHERE questions.heading = 3 ORDER BY RANDOM() LIMIT 3 
    UNION 
    SELECT questions.question, questions_headings.title FROM questions JOIN questions_headings ON questions.heading=questions_headings.id WHERE questions.heading IN (1,2,3) ORDER BY RANDOM() LIMIT 10 
) LIMIT 10 

的想法是,让10/3 = 3,从每一个标题,然后得到的残留物(由于舍入错误)。因为最后一次查询可能导致已经获取的数据,所以我们限制为10,所以我们明确地获得我们需要的额外1,然后再次限制整个事情。这应该导致均匀分布的值。

+0

问题是,应用程序将收到未知数​​量的'questions.heading'标识。有没有办法与'纯SQL'做到这一点? – dave 2010-06-24 08:08:05

+0

在db2中,我可以使用row_number()来为你写一个查询,但是我想不出在MySQL中的一种方式。 – 2010-06-24 08:21:45

+0

出于好奇,你能提供查询吗? – dave 2010-06-24 08:25:17

0

下面将在DB2工作(并可以很容易地移植到其他数据库支持ROW_NUMBER):

SELECT * FROM (
    SELECT question, title 
    FROM (
    SELECT questions.question, questions_headings.title, 
     row_number() over(PARTITION BY questions.headings ORDER BY rand()) rn 
    FROM questions JOIN questions_headings ON questions.heading=questions_headings.id 
    WHERE questions.heading IN (1,2,3) 
) 
    WHERE rn <= 3 
    UNION 
    SELECT questions.question, questions_headings.title 
    FROM questions JOIN questions_headings ON questions.heading=questions_headings.id 
    WHERE questions.heading = 1 
    ORDER BY RAND() 
    FETCH FIRST 10 ROWS ONLY 
) 
FETCH FIRST 10 ROWS ONLY 
0

这适用于PostgreSQL的:

SELECT q2.row - (SELECT count(*) 
       FROM questions q3 
       WHERE q3.heading IN (1, 2, 3) 
       AND q3.heading < q2.heading) AS ord, 
     q2.heading, q2.question 
FROM (
    SELECT row_number() OVER (ORDER BY heading, random()) as row, 
     q1.id, q1.heading, q1.question 
    FROM questions q1 
    WHERE heading IN (1,2,3) 
    ORDER BY heading, row) AS q2 
ORDER BY ord 
LIMIT 10; 

我无法测试的MySQL版本,但这应该可能是:

SELECT q2.row - (SELECT count(*) 
       FROM questions q3 
       WHERE q3.heading IN (1, 2, 3) 
       AND q3.heading < q2.heading) AS ord, 
     q2.heading, q2.question 
FROM (
    SELECT @rownum:[email protected]+1 AS row, 
     q1.id, q1.heading, q1.question 
    FROM questions q1, (SELECT @rownum:=0) r 
    WHERE heading IN (1,2,3) 
    ORDER BY heading, rand()) AS q2 
ORDER BY ord 
LIMIT 10; 

问题的关键是要记录,以便有ex来自任何选定标题的第二个问题之前的每个选定标题中的一个问题,等等。如果对某些标题没有足够的问题,它仍然会在其他标题上平均分配。

相关问题