2010-08-31 10 views
11

Soy nuevo en SQL. Tengo una base de datos con datos para diferentes exámenes, por ejemplo:SQL - columnas para diferentes categorías

Student Test Grade 
-------------------- 
St1 T1 A 
St2 T1 B 
St3 T1 B 
St1 T2 B 
St2 T2 B 
St3 T2 A 
St1 T3 A 
St2 T3 C 
St3 T3 B 

Entonces, me gustaría para imprimir un informe utilizando las pruebas (T1, T2 y T3) como columnas:

Student T1 T2 T3 
---------------------- 
St1  A B A 
St2  B B C 
St3  B A B 

I he intentado cosas diferentes, pero me quedé atascado en cómo producir una impresión de ese tipo. ¡Cualquier ayuda es apreciada!

+1

formatear con el botón "código" le permitirá usar una fuente de ancho fijo, ayudando a estas tablas a alinearse y ser más legible – ford

Respuesta

10

Uso:

SELECT t.student, 
     MAX(CASE WHEN t.test = 'T1' THEN t.grade END) AS T1, 
     MAX(CASE WHEN t.test = 'T2' THEN t.grade END) AS T2, 
     MAX(CASE WHEN t.test = 'T3' THEN t.grade END) AS T3 
    FROM TABLE t 
GROUP BY t.student 
+0

Hola, ¡Eres genial! Muchas gracias! Funcionó a la perfección! ¡Salud! -Mike –

+1

@Mike Santos: De nada, y bienvenidos a SO. –

1

le pregunté a un semejante question un tiempo atrás. Necesita algo parecido a una tabla dinámica, pero eso no está disponible en SQLite (hasta donde yo sé).

+0

¡Gracias por la información! Vi tu pregunta. –

1

Creo que si se va a expandir este sistema para incluir más información a continuación, usted podría beneficiarse de reelaboración de su base de datos, me gustaría construirlo así:

Nombre de la tabla = Negrita

nombre de columna = en cursiva

estudiantes:

  • SID (clave principal)
  • Otra información sobre el estudiante

pruebas:

  • TID (clave principal)
  • Más información sobre la prueba de

grados de la prueba

  • GID (clave principal)
  • TID (clave externa)
  • SID (clave externa)
  • Grado

Esta estructura se basa en una idea llamada normalización de base de datos (obtendrá mucha información si la busca en google).A continuación, le daré un resumen parcial, pero si va a hacer mucho SQL, debería leerlo usted mismo:

Lo primero que debe saber es que una clave principal es solo un identificador único, es no suele ser parte de la información (sin embargo, dado que es única, cada dato debe tener un valor diferente para su clave principal), y una clave externa es una forma de referenciar una fila en una tabla desde una fila en otra tabla, utilizando el clave: por ejemplo, aquí la clave externa SID en cada calificación hace referencia a un solo alumno, según su clave principal SID.

p. Ej. el alumno uno tiene SID 1 y todas sus pruebas tienen 1 en la columna SID. lo mismo para el estudiante 2, 3, 4, y así sucesivamente.

La idea básica de normalizar, es que todos los datos únicos se almacenan solo una vez y luego se referencian en los otros lugares que lo usan (Si observa cómo se estructuran las claves en el ejemplo, se almacena toda la información del estudiante en una tabla y luego se hace referencia en sus calificaciones de prueba, en lugar de duplicarse en cada grado).

Para recuperar lo que quiere de estas tablas que yo usaría este (su escrito en PHP):

$sql = 'SELECT * FROM Tests ORDER BY TID'; 
$tempresult = mysql_query($sql); 
while($temprow = mysql_fetch_array($tempresult)){ 
    echo $temprow['TID']; 
} 

$sql = 'SELECT * FROM Students'; 
$result = mysql_query($sql); 
while($row = mysql_fetch_array($result)){ 
    echo '\n'.$row['SID']; 
    $sql = 'SELECT * FROM Grades WHERE SID='.$row['SID'].' ORDER BY TID'; 
    $result2 = mysql_query($sql); 
    while($row2 = mysql_fetch_array($result2)){ 
     echo ' '.$rows['Grade']; 
    } 
} 

Puede agregar formato a esto en las declaraciones de eco y también imprimir cualquiera de la información adicional que elija para agregar Si tiene preguntas, pregúnteles.

EDIT: He leído los otros, y estoy de acuerdo en que su método es probablemente superior, lo único de lo que no estoy seguro es si las tablas pivote pueden expandirse para manejar un número variable de pruebas, si puede (o no será necesario), luego sugiero su método, de lo contrario, creo que esto podría tener un lugar en su aplicación.

+0

¡Muchas gracias por la información detallada! ¡Realmente aprecio eso! ¡Gracias! -Mike –

0

Trate Esta

SELECT Student, MAX(CASE WHEN Test = 'T1' THEN Grade END) AS T1, 
    MAX(CASE WHEN Test = 'T2' THEN Grade END) AS T2, 
    MAX(CASE WHEN Test = 'T3' THEN Grade END) AS T3 FROM tablename GROUP BY Student 

usar su nombre de tabla en lugar de "nombre de tabla".

1

Hay un par de formas de hacerlo, las cuales (en SQL puro y no código que genera un comando SQL) requieren que se conozca y se solucione el número de columnas. El más sencillo de implementar serían:

SELECT eg.Student, 
(SELECT Grade from ExamGrade eg1 WHERE eg1.Student = eg.Student AND Test = 'T1') AS T1 
(SELECT Grade from ExamGrade eg2 WHERE eg2.Student = eg.Student AND Test = 'T2') AS T2 
(SELECT Grade from ExamGrade eg3 WHERE eg3.Student = eg.Student AND Test = 'T3') AS T3 
FROM ExamGrade eg 

Esto funciona en prácticamente cualquier entorno que incluye SQLite, y se podría hacer un poco más elegante, con una función escalar de valor GetTest() que tomaría el estudiante y la prueba numera y devuelve la calificación. Sin embargo, en cualquier caso, esto no está funcionando ni está cerrado al cambio; consultará la tabla N-squared times para N tests, y si agrega una cuarta prueba, esta consulta tendrá que cambiar para incluirla en el informe.

Si la combinación de Estudiante y Prueba es única, y está trabajando en una base de datos con funcionalidad Pivot (que al parecer SQLite no tiene), puede usar una consulta Pivot con casi cualquier agregador (el MAX/MIN/AVG/SUM de un conjunto con un solo valor es ese valor). Los siguientes trabajos en MSS2005:

SELECT Student, T1, T2, T3 
FROM (Select Student, Test, Grade FROM ExamGrade) As SourceQuery 
PIVOT (MAX(Grade) FOR Test IN (T1, T2, T3)) AS PivotTable 

Esto será más eficiente y mucho más elegante. Las listas de columnas todavía no se pueden determinar dinámicamente como AFAIK, pero son triviales para generar si está realizando esta consulta desde el código de la aplicación o utilizando el proceso almacenado sp_executesql en MS SQL Server para generar una consulta desde otro proceso almacenado o función.

+0

¡Muchas gracias por la información! –

Cuestiones relacionadas