2017-12-08 5 views
0

Ich habe zwei Abfragen und ich möchte, dass sie in einer Abfrage kombinierenKombinieren Sie zwei einfache SQL-Abfragen zwei eine Abfrage

erste Abfrage: Diese Abfrage findet in jedem Fach für jeden Schüler die durchschnittliche:

SELECT 
    StudentFirstName, StudentLastName, ClassName, 
    AVG(Grade) AS 'average for this subject' 
FROM tests 
INNER JOIN students ON tests.StudentID = students.StudentID 
GROUP BY StudentFirstName, StudentLastName, ClassName; 

2. Abfrage: diese Abfrage findet den Durchschnitt für jeden Schüler seines Gesamtdurchschnitt für ganze seine Abschlussnoten:

SELECT 
    StudentFirstName, StudentLastName, AVG(average) AS total_average 
FROM 
    (SELECT 
     StudentFirstName, StudentLastName, AVG(Grade) AS average 
    FROM 
     tests 
    INNER JOIN 
     students ON tests.StudentID = students.StudentID 
    GROUP BY 
     StudentFirstName, StudentLastName, ClassName) AS t 
GROUP BY 
    StudentFirstName, StudentLastName; 

zum Beispiel: die Qualitäten von mir (auch bekannt als Error404) sind:

  • Algebra: erste Prüfung: 99, zweite Prüfung: 97, dritte Prüfung: 96 --->erste Abfrage gibt Durchschnitt: 97,3333 für dieses Thema

  • maschinelles Lernen: erste Prüfung: 95, zweite Prüfung: 94 --->erste Abfrage gibt Durchschnitt: 94,5 für dieses Thema

zweite Abfrage gibt zu tal durchschnittlich AVG (97.3333,94.5) = 95,91665 für Studenten namens error404

Tabelle 1 - Students:

 pk-INT   VARCHAR    VARCHAR 
    +-----------+------------------+-----------------+ 
    | StudentID | StudentFirstName | StudentLastName | 
    +-----------+------------------+-----------------+ 
    |   1 | agam    | rafaeli   | 
    |   2 | amir    | aizinger  | 
    |   3 | avi    | caspi   | 
    |   4 | avia    | wolf   | 
    +-----------+------------------+-----------------+ 

Tabelle 2 - Tests:

PK-VARCHR PK-VARCHR  PK&FK-INT INT 
+------------+------------+-----------+-------+ 
| TestDate | ClassName | StudentID | Grade | 
+------------+------------+-----------+-------+ 
| 2017-07-01 | Algebra |   1 | 88 | 
| 2017-08-02 | Algo  |   1 | 97 | 
| 2017-09-01 | Algebra |   1 | 80 | 
| 2017-09-01 | Algebra |   1 | 97 | 
| 2017-09-01 | Set-theory |   1 | 85 | 
| 2017-09-04 | Calcules |   1 | 86 | 
| 2016-05-03 | Set-theory |   2 | 84 | 
| 2016-07-02 | Calcules |   2 | 89 | 
| 2016-07-04 | Algo  |   2 | 83 | 
| 2016-07-05 | Algebra |   2 | 79 | 
| 2016-06-03 | Algebra |   3 | 99 | 
| 2016-07-02 | Algo  |   3 | 97 | 
| 2016-07-03 | Calcules |   3 | 96 | 
| 2016-09-03 | Set-theory |   3 | 95 | 
| 2016-06-03 | Algebra |   4 | 78 | 
+------------+------------+-----------+-------+ 

Beispieldaten:

DROP DATABASE IF EXISTS error404; 
CREATE DATABASE error404; 

USE error404 

CREATE TABLE students 
(
    StudentID  INT NOT NULL AUTO_INCREMENT, 
    StudentFirstName VARCHAR(25), 
    StudentLastName VARCHAR(25), 
    PRIMARY KEY (StudentID) 
); 

INSERT INTO students (StudentFirstName, StudentLastName) 
VALUES ('agam', 'rafaeli'), ('amir', 'aizinger'), ('avi', 'caspi'), 
     ('avia', 'wolf '); 

CREATE TABLE tests 
(
    testid INT NOT NULL AUTO_INCREMENT, 
    TestDate DATE, 
    ClassName VARCHAR(25), 
    StudentID INT NOT NULL, 
    Grade  INT NOT NULL, 
    PRIMARY KEY (testid), 
    KEY (StudentID) 
); 

INSERT INTO tests (TestDate, ClassName, StudentID, Grade) 
VALUES ('2017-07-01', 'Algebra', 1, 88), 
     ('2017-08-02', 'Algo', 1, 97), 
     ('2017-09-01', 'Algebra', 1, 80), 
     ('2017-09-01', 'Algebra', 1, 97), 
     ('2017-09-01', 'Set-theory', 1, 85), 
     ('2017-09-04', 'Calculus', 1, 86), 
     ('2016-05-03', 'Set-theory', 2, 84), 
     ('2016-07-02', 'Calculus', 2, 89), 
     ('2016-07-04', 'Algo', 2, 83), 
     ('2016-07-05', 'Algebra', 2, 79), 
     ('2016-06-03', 'Algebra', 3, 99), 
     ('2016-07-02', 'Algo', 3, 97), 
     ('2016-07-03', 'Calculus', 3, 96), 
     ('2016-09-03', 'Set-theory', 3, 95), 
     ('2016-06-03', 'Algebra', 4, 78); 

Ich möchte dieses Ergebnis:

+--------------+--------------+--------------+--------------+--------------+ 
| StFirstName | StLastName | ClassName | aveInSubject | totalAve  | 
+--------------+--------------+--------------+--------------+--------------+ 
| name1  | lname1  | algebra  | 80   | 87   | 
| name1  | lname1  | algo   | 88   | 87   | 
| name1  | lname1  | calcul  | 93   | 87   | 
| name2  | lname2  | algebra  | 70   | 74.3  | 
| name2  | lname2  | algo   | 76   | 74.3  | 
| name2  | lname2  | calcul  | 77   | 74.3  | 
+--------------+--------------+--------------+--------------+--------------+ 

Antwort

1

Sie das Ergebnis pro Fach Durchschnitt und durchschnittliche pro Schüler join können.

SELECT t1.*,t2.totalAvg 
FROM (SELECT StudentFirstName,StudentLastName,ClassName,AVG(Grade) AS `average for this subject` 
     FROM tests 
     INNER JOIN students ON tests.StudentID=students.StudentID 
     GROUP BY StudentFirstName,StudentLastName,ClassName 
    ) t1 
JOIN (SELECT StudentFirstName,StudentLastName,AVG(`average for this subject`) as totalAvg 
     FROM (SELECT StudentFirstName,StudentLastName,ClassName,AVG(Grade) AS `average for this subject` 
      FROM tests 
      INNER JOIN students ON tests.StudentID=students.StudentID 
      GROUP BY StudentFirstName,StudentLastName,ClassName 
      ) t 
     GROUP BY StudentFirstName,StudentLastName 
    ) t2 
ON t1.StudentFirstName=t2.StudentFirstName and t1.StudentLastName=t2.StudentLastName 

EDIT: Für zukünftige Versionen von MySQL (ab Version 8.0) mit Fensterfunktionen könnte die Abfrage zu vereinfachen

select studentfirstname,studentlastname,classname,avgPerSubject 
,sum(avgPerSubject) over w/count(*) over w as totalAvg 
from (select distinct 
     s.studentfirstname,s.studentlastname,t.classname, 
     avg(t.grade) over(partition by s.studentfirstname,s.studentlastname,t.classname) as avgPerSubject 
     from tests t 
     join students s on s.studentid=t.studentid 
    ) t 
window w as (partition by studentfirstname,studentlastname) 
+0

Dies gibt falsches Ergebnis für ‚totalavg‘ Spalte soll die Gesamt avg sein der Durchschnitt der Durchschnittswerte. Das heißt, mein Durchschnitt in der Algebra ist 88,33, mein Durchschnitt in Algo ist 97, mein Durchschnitt in Cacles ist 86, mein Durchschnitt in der Algebra ist 77,5. also sollte mein totalavg: (88.33 + 97 + 86 + 77.7)/4 = 87.208 und ** nicht ** 86.1429 wie diese Abfrage gibt, kannst du bitte editieren? –

+0

name1, name2 ??? – Strawberry

+0

versuchen Sie, den Durchschnitt pro Schüler oder Durchschnitt Durchschnitt pro Fach pro Schüler zu bekommen? –