在每个分区中选择具有指定记录数的随机分区记录

时间:2011-12-26 12:29:43

标签: sql sql-server tsql

我们有一个表(名为QuestionBank),每个问题都存储在该表中:

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

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

请注意,“位置”列中的值没有意义,它只是在主题中对类似问题进行分区。

目标是选择N条记录,其中X条记录为Harness = 1,Y记录硬度= 2,Z记录硬度= 3,等等;使用此约束,尽可能没有在结果集中返回类似主题和位置的记录。

例如,Id = 4和Id = 8的记录在Topic和Position中都相似,因此希望其中一个记录在结果集中。

2 个答案:

答案 0 :(得分:1)

这是一种方式。

  1. 首先,如果任何Topic, Position有多个问题,则为每个问题分配一个随机排序RN1
  2. 然后在每组中随机排序。 1 RN1的所有2值显然会在进入Topic, Position之前先订购,表示特定ROW_NUMBER组合的第二个问题。
  3. 然后在由Hardness分区的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 更容易。
  4. {{1}}

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

答案 1 :(得分:0)

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

选择随机问题:

  1. 选择硬度1的所有记录到临时表
  2. 使用rand()选择其中一个
  3. 测试以前是否选择了具有相同主题/位置的任务,如果是,则不必选择问题并将其从第1点中的选择中删除。
  4. 执行步骤2到3,直到您有指定硬度的N条记录
  5. 执行其他硬度值的步骤1到4.