28. februar 2006 - 12:06Der er
20 kommentarer og 1 løsning
Vælge værdier der eksistere mere end én gang.
En kammerat og jeg er igang med at konstruere forespørgsler som et led i en opgave på vores studie.
Vi har en studiedatabase, med studerende og deres adresser, div. klasser, fag og de karakterer de studerende har fået i de forskellige fag.
Den opgave vi sidder fast i er, hvor vi skal finde karaktererne på alle de elever der har bestået 2 fag eller mere (dvs. har en karakter over 5). Det er lykkedes os at få lavet forespørgslen således, at vi nu har hentet alle studerende og deres karakterer der er over 5.
Vi står med een studerende der har 3 fag bestået, en der har 2 fag bestået og 2 der kun har bestået et fag. Nu er problemet at vi skal have sorteret de sidste to studerende fra i vores WHERE statement, således at vi kun har de to første studerende med.
Forespørgslen indtil videre: -------------------------------------------------------------- SELECT S_grade.Grade, Student.Name, Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student=Student.Student WHERE (S_grade.Grade>5);
S_grade.Grade er karakteren, Student.Name siger sig selv, Student.Student er ID-nummeret på den studerende da det samme navn optræder flere gange i Student.Name. S_grade indeholder fag og karakteren i faget.
Vi har forsøgt at bruge HAVING og COUNT, men kan ikke få det til at virke. Er der ikke en kommando der kan udtrække rækker hvor en værdi optræder mere end een gang ( i vores tilfælde, student.student).
SELECT S_grade.Grade, Student.Name, Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student=Student.Student WHERE COUNT(S_grade.Grade>5) > 1;
Try making an Aggregate query (Totals). You do this by pressing the icon on the menu bar which looks like Z. This will add total: row in the area bellow the window showing the tables. In the row you will see "Group By" in all columns. You need to change the column for Grade from "Group By" to "Count". This will (should) give you the number each student has a charcater over 5.
Normally you can use TOP 2 in a query to give you the two two students who have passed the most exams. Problme with with using TOP is that if more than 1 student ha sth esame number of passes then they all will be included, which i dont think is what you want.
Anyway, hope you understand all this, if not drop a comment.
SELECT S_grade.Grade, Count(S_grade.Grade) AS AntalOfGrade, Student.Name, Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student = Student.Student GROUP BY S_grade.Grade, Student.Name, Student.Student HAVING (((S_grade.Grade)>5) AND ((Count(S_grade.Grade))>2));
Terry > Not quite sure what you mean by that. I'm not interested in the number of grades, that exceeds 5. I already have the grades that exceeds five. What I want, is the students which have only passed 1 class, to me removed from the list, so what remains the a list of students which have passed 2 or more classes.
jensen363 > Kører jeg den, bliver den godt nok afvilket - men den vender ikke tilbage med noget resultat. Desuden, tæller den ikke kun antallet af karakterer der viser sig mere end een gang? Se eventuelt svar til terry.
SELECT Student.Name, Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student = Student.Student GROUP BY Student.Name, Student.Student, S_grade.Grade HAVING (((S_grade.Grade)>5) AND ((Count(S_grade.Grade))>=2));
jensen393 > Sorry to tell you, men den vender stadig tilbage med intet. Ændrer jeg derimod >=2 til >=1, så kommer den med alle sammen - altså også dem der kun har bestået eet fag. Den laver altså et eller anden galt, når den tæller.
Burde den sidste linje egentlig ikke også se sådan ud: HAVING (((S_grade.Grade)>5) AND ((Count(S_grade.Student))>=2)); - så den tæller S_grade.Student istedet for S_grade.Grade. Den skal jo finde Students hvor deres id dukker op mere end een gang...
Det er princippielt ligegyldigt om du benytter ((Count(S_grade.Student))>=2)) eller ((Count(S_grade.Grade))>=2)) .... forespørgslen tæller antallet af forekomster, og om Student forekommer 2 eller flere gange, eller der er hit på grade 2 eller flere gange er lige fedt.
Jeg har oprettet et tilsvarende datasæt, og programkoden udføres korrekt uanset hvad du vælger ...
SELECT Student.Name, Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student = Student.Student WHERE (((S_grade.Grade)>5)) GROUP BY Student.Name, Student.Student HAVING (((Count(S_grade.Grade))>=2));
Jensen363 > Præcis, nu mangler vi blot at få karakterne på også - altså få vist de forskellige karakterer de har fået. Skriver man S_grade.Grade på i SELECT toppen, brokker den sig bare.
Ved ikke lige, om det et tilladt at lave afledte forespørgsler, men her er et eksempel hvor du benytter "j)" som mellemled :
TRANSFORM Sum(S_grade.Grade) AS SumOfGrade SELECT [j)].Name, [j)].Student FROM S_grade INNER JOIN [j)] ON S_grade.Student = [j)].Student GROUP BY [j)].Name, [j)].Student PIVOT S_grade.Sid;
SELECT Student.Name, Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student = Student.Student WHERE (((S_grade.Grade)>5)) GROUP BY Student.Name, Student.Student HAVING (((Count(S_grade.Grade))>=2));
Så opretter du en en ny forespørgsel, og indsætter denne :
TRANSFORM Sum(S_grade.Grade) AS SumOfGrade SELECT [j)].Name, [j)].Student FROM S_grade INNER JOIN [j)] ON S_grade.Student = [j)].Student GROUP BY [j)].Name, [j)].Student PIVOT S_grade.Sid;
Den sidste er en såkaldt krydstabuleringsforespørgsel
Det blev ikke lige korrekt og så tror jeg ikke vi kan forklare os ud af de to forespørgsler, lidt for indviklet til vores niveau.
Er det muligt at få den endelige skema til at indeholde tre kolonner: Name, Student og Grade? Dvs. så f.eks. Kim får 2 rækker til hans to karakterer over 5?
Nå, så fandt jeg endelig ud af den selv. Lavede en query i query.
SELECT Student.Student, Student.Name, S_grade.Grade FROM S_grade INNER JOIN Student ON S_grade.Student = Student.Student WHERE ((S_Grade.Grade)>5) and Student.Student IN (SELECT Student.Student FROM S_grade INNER JOIN Student ON S_grade.Student = Student.Student WHERE (((S_grade.Grade)>5)) GROUP BY Student.Name, Student.Student HAVING (((Count(S_grade.Grade))>=2)));
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.