2013-02-21 12 views
7

Ho un problema nella mia query SQLCome ottenere valori distinti in SQL Query

voglio selezionare StudentGroups distinti (SG), ma la domanda mi dà qualche repetations

Ecco il mio Query

SELECT  DISTINCT(SG.SGID), en.EnrollmentID, CR.Name AS Course, INS.Name as Instructor, 
       S.Session, SG.StartTime, SG.EndTime, EN.CreateDate 

    FROM  StudentGroups SG inner JOIN Enrollments EN ON SG.SGID = EN.SGID 
       JOIN Courses CR ON SG.CourseID = CR.CourseID 
       JOIN Class CL ON SG.ClassID = CL.ClassID 
       JOIN Instructors INS ON SG.InstructorID = INS.InstructorID 
       JOIN Sessions S ON SG.SessionID = S.SessionID 

    WHERE  EN.SGID NOT IN (SELECT SGID FROM Enrollments 
          WHERE StudentID = 45 

AGGIORNAMENTO

Questa interrogazione mi dà i seguenti dati

enter image description here

ma io non voglio ripetere SGID

+6

'DISTINCT' non è una funzione ***. È un * operatore * applicato a ** tutte ** colonne nell'elenco di selezione. –

+7

DISTINCT funziona sulla riga ** tutto **: non è possibile ottenere valori SGID DISTINCT nello stesso insieme di risultati con altre colonne. Non ha senso ... – gbn

+1

allora come posso ottenere record unici ?? @a_horse_with_no_name, @ gbn –

risposta

13

DISTINCT vale sempre per tutte le colonne restituite. Mettere le parentesi su una colonna non fa differenza nel suo comportamento.

Se volete che i vostri risultati di contenere solo valori unici di SG.GID, è possibile utilizzare una clausola GROUP BY invece - ma poi si deve decidere alcune regole per i quali i valori si desidera restituire nelle altre colonne. A tale scopo, utilizzando funzioni di aggregazione come MIN(), MAX(), COUNT(), SUM(), ecc esempio semplificato:

SELECT SG.SGID, 
     MIN(SG.START_TIME),    --the lowest start time for this sgid. 
     COUNT(DISTINCT en.EnrollmentID) --the unique enrollments for this sgid. 
    FROM StudentGroups SG 
    INNER JOIN Enrollments EN ON SG.SGID = EN.SGID 
    GROUP BY SG.SGID; 

Quando si uniscono più tabelle come nella query originale, bisogna stare attenti quando il conteggio e sommando le cose, come i duplicati dall'unione possono darti risultati errati.

Un'altra possibilità sarebbe quella di utilizzare ROW_NUMBER() per restituire una riga per ogni SGID:

SELECT * FROM (
    SELECT SG.SGID, 
      SG.START_TIME, 
      en.EnrollmentID, 
      ROW_NUMBER() OVER (PARTITION BY SGID ORDER BY SG.START_TIME) as RN 
     FROM StudentGroups SG 
     INNER JOIN Enrollments EN ON SG.SGID = EN.SGID 
    ) 
    WHERE RN = 1; 

This numeri delle righe per ogni SGID, da 1 e filtrate per il valore di SG.START_TIME. Restituirà la prima riga con la prima ora di inizio per ogni SGID. Se più righe hanno la stessa ora di inizio, selezionerà una di queste, più o meno a caso. È possibile aggiungere altri campi alla clausola ORDER BY per definire ulteriormente quali righe vengono restituite.

5

Utilizzare la clausola GROUP BY quando DISTINCT non funziona per l'output desiderato.

Problemi correlati