2011-12-26 25 views
4

我们在其上存储的每一个问题一个表(名为试题库)选择随机分区战绩:有记录的指定数量在每个分区

Id  Topic  Hardness Position 
4  1   3   4 
5  1   2   1 
6  1   1   2 
7  1   3   3 
8  1   3   4 
9  2   2   1 
10  2   2   2 
11  2   3   3 
12  3   1   1 
13  3   1   1 
14  3   1   2 

每一个问题属于一个主题,有它自己的硬度和位置(基于其内容的每个类似问题在相应主题上具有相同的位置)。

请注意,位置列中的值没有意义,它只是在主题中划分相似的问题。

目标是以随机的方式选择带有Harness = 1的X记录和Hardness = 2的Y记录和Hardness = 3的Z记录等的N个记录;这个约束尽可能地没有结果集中返回的具有相似主题和位置的记录。

例如,Id = 4和Id = 8的记录在主题和位置中都是相似的,因此希望其中的一个在结果集中。

回答

1

这是一种方法。

  1. 首先,如果有任何Topic, Position有多个问题分配给每个这些随机排序RN1
  2. 然后按每个组随机排序。显然RN1的所有1值将首先排序,然后才能进入2,这表示特定Topic, Position组合的第二个问题。
  3. 然后使用由Hardness分区的ROW_NUMBER计算中的结果,使最终的SELECT更容易。

WITH T1 
    AS (SELECT *, 
       Row_number() OVER (PARTITION BY Topic, Position 
             ORDER BY Newid()) AS RN1 
     FROM QuestionBank), 
    T2 
    AS (SELECT *, 
       Row_number() OVER (ORDER BY RN1, Newid()) AS RN2 
     FROM T1), 
    T3 
    AS (SELECT *, 
       Row_number() OVER (PARTITION BY Hardness 
             ORDER BY RN2) AS RN3 
     FROM T2) 
SELECT Id, 
     Topic, 
     Hardness, 
     Position 
FROM T3 
WHERE (Hardness = 1 
     AND RN3 <= 3) 
     OR (Hardness = 2 
      AND RN3 <= 2) 
     OR (Hardness = 3 
      AND RN3 <= 2) 
ORDER BY Topic, 
      Position, 
      Hardness 

如果您每次只选择一小部分表格,可能会有更高效的方法。

+0

非常感谢你的解决方案@Martin。 我从昨天开始工作,它的工作完美。 – 2011-12-27 08:31:44

+0

现在我陷入另一个问题: 如果我打算限制与话题相关的记录数量而不是硬度。解决方案是什么? 例如Topic = 1的3个记录,Topic = 2的4个记录和Topic = 3的2个记录(而不是例如2个Hardness = 1的记录,...) 预先感谢您的好意。 – 2011-12-27 08:47:10

0

您可以一个WHILE周期一次选择一个问题。

要选择随机问题:

  1. 选择硬度1的所有记录到一个临时表
  2. 使用rand()选择其中一个
  3. 测试,如果有预先用同样的选择questin话题/位置,如果是这样,则不必选择所选问题并将其从第1点中选择的问题中删除。
  4. 执行步骤2至3,直到您具有指定的硬度的N个记录
  5. 对其他硬度值执行步骤1至4。
相关问题