SQL - hämta data ur en tabell beroende på vad som inte finns i en annan

Permalänk
Medlem

SQL - hämta data ur en tabell beroende på vad som inte finns i en annan

Suttit några timmar och börjar ge upp nu.

Jag har två tabeller: tblStudent och tblClassStudent. tblStudent innehåller bara studenter och tblClassStudent innehåller en koppling mellan studenterna och kurserna de läser (fldClassID och fldStudentID).

I det här fallet behöver jag en lista på de studenter som inte är registrerade på en viss kurs (1). Den här satsen är det närmaste jag kommer.

SELECT * FROM tblStudent s FULL OUTER JOIN tblClassStudent x ON s.fldStudentID = x.fldStudentID WHERE x.fldClassID !=0 OR x.fldClassID IS NULL

Resultatet blir följande om man söker på ett ClassID som ingen är registrerad på: https://imgur.com/jzI1TVZ
Det här händer om man söker på ett ClassID där två studenter är registrerade: https://imgur.com/Xv25uCP

Problemet är att om studenter är registrerade på andra kurser också så kommer de ändå att visas (fast som att de är registrerade på andra kurser. Jag vill få studenterna unika. Finns de inte registrerade på kurs A men på kurs B så ska man bortse från Kurs B och endast visa studenter som inte är registrerade på kurs A.

Jag har provat DISTINCT utan att få det resultat jag vill.

Går det överhuvudtaget att göra i enbart SQL???

Permalänk
Medlem
Skrivet av bjrkis:

Suttit några timmar och börjar ge upp nu.

Jag har två tabeller: tblStudent och tblClassStudent. tblStudent innehåller bara studenter och tblClassStudent innehåller en koppling mellan studenterna och kurserna de läser (fldClassID och fldStudentID).

I det här fallet behöver jag en lista på de studenter som inte är registrerade på en viss kurs (1). Den här satsen är det närmaste jag kommer.

SELECT * FROM tblStudent s FULL OUTER JOIN tblClassStudent x ON s.fldStudentID = x.fldStudentID WHERE x.fldClassID !=0 OR x.fldClassID IS NULL

Resultatet blir följande om man söker på ett ClassID som ingen är registrerad på: https://imgur.com/jzI1TVZ
Det här händer om man söker på ett ClassID där två studenter är registrerade: https://imgur.com/Xv25uCP

Problemet är att om studenter är registrerade på andra kurser också så kommer de ändå att visas (fast som att de är registrerade på andra kurser. Jag vill få studenterna unika. Finns de inte registrerade på kurs A men på kurs B så ska man bortse från Kurs B och endast visa studenter som inte är registrerade på kurs A.

Jag har provat DISTINCT utan att få det resultat jag vill.

Går det överhuvudtaget att göra i enbart SQL???

Nu är jag inte jätteinsatt i ditt problem, en sak du kan laborera med är att göra någon variant där du skriver GROUP BY fldEmail på slutet t.ex. Sedan kan du fundera över möjligheten med nästlade SQL-satser.

Permalänk
Medlem

1. Använd en vanlig (inner) join. Anledningen till att du får en massa NULLs är för att du gör en full outer join;
2. Testa efter rader som motsvarar dina förväntningar (studenter som inte är registrerade på en viss kurs)

Jag löser problemet genom att testa negativt mot en inre query som väljer ut rader som inte ska finnas med.

select * from tblStudent s where not exists ( select * from tblClassStudent cs where cs.fldStudentID = s.fldStudentID and fldClassID = 1 ) from tblClassStudent fldClassID != 1

Varför skriver du förresten tbl och fld framför alla namn? Det ser onödigt ut

edit: såg din kommentar under kodexemplet, det krävdes vissa ändringar.

Visa signatur

Kom-pa-TI-bilitet

Permalänk

Som jag förstod det så ville du ha de studenter som inte är registrerade på kurs 1:

Alternativ 1:

SELECT fldStudentId FROM tblStudent MINUS SELECT fldStudentId FROM tblClassStudent WHERE fldClassID = 1

Alternativ 2:

SELECT fldStudentId FROM tblStudent s WHERE NOT EXISTS (SELECT 1 FROM tblClassStudent c WHERE c.fldStudentId = s. fldStudentId AND c.fldClassID = 1)

Permalänk
Medlem

Left join på ClassStudent med villkor på att fldClassId är null?

Skickades från m.sweclockers.com

Visa signatur

WS: Fractal Design Pop Silent | Seasonic Prime G12 GC 550W | Gigabyte B650 Eagle AX | Ryzen 7 7700 | Corsair 64GB DDR5 | Asus Xonar DX | Arch Linux (x86_64) | Eizo EV2795
HTPC: Philips 50PUS8804, Kodi samt extern usb-disk
Server: Raspberry Pi 4 | 8GB RAM | HDD 750GB | Arch Linux (armv7h)

Permalänk
Medlem

Fick du det att fungera?

Visa signatur

Grubblare

Permalänk
Medlem

Skulle använda LEFT JOINE, INNER JOINE metoden när man ska hämta från 2 olika tabeller.

Permalänk
Avstängd

Det är ganska enkelt egentligen, om jag förstår det hela rätt:

SELECT FROM tblStudent s LEFT JOIN tblClassStudent x ON s.fldStudentID = x.fldStudentID AND x.fldClassID = 1234 //Den klass du vill att de inte ska vara deltagare i WHERE x.fldClassID IS NULL

Permalänk
Medlem
Skrivet av snajk:

Det är ganska enkelt egentligen, om jag förstår det hela rätt:

SELECT FROM tblStudent s LEFT JOIN tblClassStudent x ON s.fldStudentID = x.fldStudentID AND x.fldClassID = 1234 //Den klass du vill att de inte ska vara deltagare i WHERE x.fldClassID IS NULL

Tänkte också så först men sedan la jag märke till följdkravet

Citat:

Problemet är att om studenter är registrerade på andra kurser också så kommer de ändå att visas (fast som att de är registrerade på andra kurser. Jag vill få studenterna unika. Finns de inte registrerade på kurs A men på kurs B så ska man bortse från Kurs B och endast visa studenter som inte är registrerade på kurs A.

Så vid närmare eftertanke efterfrågas väl en lista på studenter som inte har några kurser?

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Avstängd
Skrivet av Teknocide:

Tänkte också så först men sedan la jag märke till följdkravet

Så vid närmare eftertanke efterfrågas väl en lista på studenter som inte har några kurser?

Tja, frågan är ju inte så tydlig. Vad menas med "Jag vill få studenterna unika" exempelvis? Men som jag tolkar den så ska vi hitta alla studenter som inte är registrerade vid en viss kurs oavsett om de är registrerade på andra kurser eller ej, men bara en rad per student. Vilket är vad min utsökning gör. Vill man ha med flera kurser i utsökningen så får man börja fundera på DISTINCT och sannolikt att göra flera joins till klass-tabellen. Vill man ha studenter som inte är med i någon kurs får man förstås göra en inre sökning, typ:

SELECT FROM tblStudent s LEFT JOIN ( SELECT DISTINCT fldStudentID FROM tblClassStudent ) x ON s.fldStudentID = x.fldStudentID WHERE x.fldStudentID IS NULL