2012-06-03 12 views
7

asumir una estructura de tabla:¿Cómo selecciono X filas aleatorias mientras garantizo que Y ciertas filas específicas están en el resultado?

Create Table Question 
{ 
ID int pk, 
Category varchar 
Stem varchar, 
AnswerA varchar, 
... 
AnswerD varchar, 
Correct char, 
isMandatory bit 

} 

a una categoría dada, hay aproximadamente 50 preguntas. Puede haber 1-10 preguntas obligatorias.

Necesito seleccionar todas las preguntas obligatorias, y luego bastantes otras preguntas al azar para hacer un conjunto de preguntas de 20 preguntas.

+0

¿Quieres 20 preguntas de cada categoría? –

+0

Sí, pero puedo lidiar con eso, estoy contento si recibo uno a la vez. –

+0

conecta con 'union' tus consultas aleatorias y no aleatorias –

Respuesta

7

Ok ¿qué tal esto

select top 20 * from question 
where category = @category 
order by isMandatory desc, newid() 

Ver aceptado respuesta para el razonamiento detrás de newid() Random record from a database table (T-SQL)

+0

La respuesta aceptada allí no menciona 'CRYPT_GEN_RANDOM', introducida en 2008. A diferencia de' RAND' esto se evalúa por fila. –

+0

Este es un SQL no probado, ¿estás diciendo que el guid sería el mismo para todos los registros, y por lo tanto el resultado no sería aleatorio? –

+0

No. 'NEWID()' funciona bien aunque no estoy seguro del grado real de aleatoriedad que ofrece. Ese es el problema con la opción más obvia de 'RAND' (como se menciona en la respuesta que vinculó) y por qué las personas recurrieron al uso de' NEWID'. –

0
Declare @number_of_nonmandat INT 

    Select @number_of_nonmandat=count(1) 
    FROM Question 
    where isMandatory =1 

    SET @number_of_nonmandat=20-number_of_nonmandat; 

    IF(@number_of_nonmandat>0) 
    BEGIN 
     Select * 
     FROM Question 
     where isMandatory =1 
      UNION 
     SELECT TOP (@number_of_nonmandat) * 
     FROM Question 
     where isMandatory<>1 
     ORDER BY newID() 
    END 
    ELSE 
    BEGIN 
     Select top 20 * 
     FROM Question 
     where isMandatory =1 

    END 
+0

No has declarado el tipo de datos de' @ number_of_nonmandat'. – Bridge

6
;WITH T 
    AS (SELECT *, 
       ROW_NUMBER() 
        OVER (PARTITION BY Category 
          ORDER BY isMandatory DESC, CRYPT_GEN_RANDOM(4)) RN 
     FROM Question) 
SELECT * 
FROM T 
WHERE RN < = 20 
+0

Estaba interesado en el rendimiento en el 'NEWID()' contra 'CRYPT_GEN_RANDOM (4)', pero ordenando por 'CRYPT_GEN_RANDOM (4)' no aleatoriza la orden; ¿qué estoy haciendo mal? –

+0

Aquí está mi ejemplo SQL: –

+0

declare @ data table (val int) ; insertar en @ datos valores (1), (2), (3), (4), (5) –

Cuestiones relacionadas