2010-08-31 20 views
11

Ich bin neu in SQL. Ich habe eine Datenbank mit Daten für verschiedene Prüfungen, zum Beispiel:SQL - Spalten für verschiedene Kategorien

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 

Dann würde Ich mag einen Bericht drucken mit den Tests (T1, T2 und T3) als Spalt:

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

I Ich habe verschiedene Dinge ausprobiert, aber ich bin nicht weitergekommen, um einen solchen Ausdruck zu erstellen. Jede Hilfe wird geschätzt!

+1

Formatierung mit der Schaltfläche "Code" können Sie eine Schriftart mit fester Breite verwenden, so dass diese Tabellen ausgerichtet und besser lesbar sein – ford

Antwort

10

Verwendung:

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

Hallo, Sie sind großartig! Ich danke dir sehr! Es hat perfekt geklappt! Prost! -Mike –

+1

@ Mike Santos: Gern geschehen, und willkommen in SO. –

1

fragte ich eine ähnliche question eine Weile zurück. Sie benötigen etwas, das einer Pivot-Tabelle ähnelt, aber das ist in SQLite nicht verfügbar (soweit ich weiß).

+0

Vielen Dank für die Information! Ich habe deine Frage gesehen. –

1

Ich glaube, wenn Sie dieses System erweitern werden dann mehr Informationen enthalten, die Sie von Nacharbeiten Ihrer Datenbank profitieren könnte, würde ich es wie so bauen:

Tabellenname = Bold

Spaltenname = Kursive

Students:

  • SID (Primärschlüssel)
  • Weitere Informationen über den Schüler

Tests:

  • TID (Primary Key)
  • Weitere Informationen über den Test

Test-Noten

  • GID (Primary Key)
  • TID (Fremdschlüssel)
  • SID (Foreign Key)
  • Grade

Diese Struktur basiert auf einer Idee namens Datenbank-Normalisierung (Sie erhalten viele Informationen, wenn Sie es googeln).Ich gebe Ihnen eine kurze Zusammenfassung unten, aber wenn Sie viel SQL machen, sollten Sie selbst darüber nachlesen:

Das erste, was zu wissen ist, dass ein Primärschlüssel nur eine eindeutige Kennung ist, ist es normalerweise kein Teil der Information (da es jedoch eindeutig ist, muss jedes Datum einen anderen Wert für seinen Primärschlüssel haben), und ein Fremdschlüssel ist eine Möglichkeit, eine Zeile in einer Tabelle aus einer Zeile in einer anderen Tabelle zu referenzieren Schlüssel: zum Beispiel hier der Fremdschlüssel SID in jeder Klasse verweist auf einen einzelnen Schüler, basierend auf ihrem Primärschlüssel SID.

z.B. Schüler hat SID 1 und alle seine Tests haben 1 in der Spalte SID. Gleiches gilt für Schüler 2, 3, 4 und so weiter.

Die Grundidee der Normalisierung besteht darin, dass alle eindeutigen Daten nur einmal gespeichert und dann an den anderen Stellen, an denen sie verwendet werden, referenziert werden (Wenn Sie im Beispiel sehen, wie die Schlüssel strukturiert sind, werden alle Schülerinformationen gespeichert in einer Tabelle und dann in ihren Prüfungsnoten verwiesen, anstatt in jeder Klasse doppelt zu sein).

abzurufen, was man aus diesen Tabellen möchte ich diese verwenden würde (seine in PHP geschrieben):

$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']; 
    } 
} 

Sie auf diese Formatierung hinzufügen können in den Echo Aussagen und auch jede weitere Informationen drucken Sie wählen hinzufügen. Wenn Sie Fragen haben, fragen Sie sie.

EDIT: Ich habe die anderen gelesen und stimme zu, dass ihre Methode aller Wahrscheinlichkeit nach überlegen ist, die einzige Sache, über die ich nicht sicher bin, ob Pivot-Tabellen erweitern können, um eine variierende Anzahl von Tests zu behandeln, wenn es kann (oder wirst du nicht brauchen), dann schlage ich ihre Methode vor, ansonsten denke ich, dass dies in deiner Bewerbung einen Platz haben könnte.

+0

Vielen Dank für die detaillierten Informationen! Ich schätze das sehr! Vielen Dank! -Mike –

0

Try This

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 

Ihre Tabellennamen verwenden anstelle von "Tablename".

1

Es gibt mehrere Möglichkeiten, dies zu tun, die beide (in reinem SQL und nicht in Code, der einen SQL-Befehl generiert) erfordern, dass die Anzahl der Spalten bekannt und behoben ist. Die einfachste wäre zu implementieren:

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 

Dies wird praktisch jede Umgebung einschließlich SQLite arbeiten, und es könnte ein bisschen mehr elegant mit einer skalarwertige Funktion GetTest() gemacht wird, dass der Schüler und Test nehmen würde Nummer und geben Sie die Note zurück. In jedem Fall ist dies jedoch weder performant noch zu ändern; Es fragt die Tabelle N-Quadrat-Zeiten für N-Tests ab, und wenn Sie einen vierten Test hinzufügen, muss diese Abfrage geändert werden, um sie in den Bericht aufzunehmen.

Wenn die Kombination von Studenten und Test einzigartig ist, und Sie sind in einer Datenbank mit Pivot-Funktionalität arbeiten (die anscheinend SQLite nicht hat), können Sie eine Pivot-Abfrage mit fast jedem Aggregator verwenden können (der MAX/MIN/AVG/SUMME einer Menge mit einem einzelnen Wert ist dieser Wert). Folgendes funktioniert in 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 

Dies wird leistungsfähiger sein, und es ist viel eleganter. Die Spaltenlisten können immer noch nicht dynamisch nach AFAIK bestimmt werden, aber sie sind einfach zu generieren, wenn Sie diese Abfrage über den Anwendungscode ausführen oder den in sp_executesql integrierten gespeicherten Prozess in MS SQL Server verwenden, um eine Abfrage aus einem anderen gespeicherten Prozess zu generieren Funktion.

+0

Vielen Dank für die Informationen! –

Verwandte Themen