2013-02-21 15 views
7

Mam problem w moim zapytaniu SQLJak uzyskać wartości Distinct w SQL Query

chcę wybrać odrębny StudentGroups (SG), ale kwerendy daje mi jakieś repetations

Oto moja Zapytanie

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 

AKTUALIZACJA

Ten kwerendy daje mi następujące dane

enter image description here

ale nie chcę powtarzane SGID

+6

'DISTINCT' to *** nie *** funkcja. Jest to * operator * zastosowany do ** wszystkich ** kolumn na liście wyboru. –

+7

DISTINCT działa w wierszu ** whole: nie można uzyskać wartości DISTINCT SGID w tym samym zestawie wyników z innymi kolumnami. To nie ma sensu ... – gbn

+1

to jak mogę uzyskać unikalne rekordy? @a_horse_with_no_name, @ gbn –

Odpowiedz

13

DISTINCT zawsze odnosi się do wszystkich kolumn zwracana. Umieszczanie nawiasów wokół jednej kolumny nie ma znaczenia w jego zachowaniu.

Jeśli chcesz, aby Twoje wyniki będą zawierać tylko unikalne wartości od SG.GID, można użyć klauzuli GROUP BY zamiast - ale wtedy musisz zdecydować pewne zasady, dla których wartości chcesz powrócić w innych kolumnach. Można to zrobić za pomocą funkcji agregujących jak MIN(), MAX(), COUNT(), SUM() itd uproszczony przykład:

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; 

Podczas łączenia wielu tabel jak w pierwotnym zapytaniu, trzeba być ostrożnym przy liczeniu i zsumowanie rzeczy, jak duplikaty z łączenia mogą dać niepoprawne wyniki.

Innym rozwiązaniem mogłoby być użycie ROW_NUMBER() powrotu jeden wiersz dla każdej 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; 

liczbową rzędy dla każdego SGID, rozpoczynając od dnia 1 i sortowane przez wartość SG.START_TIME. Zwróci jeden wiersz z najwcześniejszym czasem rozpoczęcia dla każdego SGID. Jeśli wiele wierszy ma taki sam czas rozpoczęcia, wybierze dowolne z nich, mniej lub bardziej losowo. Możesz dodać więcej pól do klauzuli ORDER BY, aby dokładniej określić, które wiersze są zwracane.

5

Należy użyć klauzuli GROUP BY, gdy DISTINCT nie działa dla pożądanego wyniku.

Powiązane problemy