2013-02-21 33 views
7

Tôi có một vấn đề trong truy vấn SQL của tôiLàm thế nào để có được giá trị riêng biệt trong SQL Query

tôi muốn chọn StudentGroups DISTINCT (SG) nhưng truy vấn mang lại cho tôi một số repetations

đây là Query tôi

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 

CẬP NHẬT

truy vấn này mang lại cho tôi dữ liệu sau

enter image description here

nhưng tôi không muốn lặp lại SGID

+6

'DISTINCT' là *** không *** chức năng. Đó là toán tử * được áp dụng cho ** tất cả ** cột trong danh sách chọn. –

+7

DISTINCT hoạt động trên hàng ** toàn bộ **: bạn không thể nhận giá trị DISTINCT SGID trong cùng một tập hợp kết quả với các cột khác. Nó không có ý nghĩa ... – gbn

+1

thì làm cách nào tôi có thể có được các bản ghi độc nhất ?? @a_horse_with_no_name, @ gbn –

Trả lời

13

DISTINCT luôn áp dụng cho tất cả các cột trở lại. Việc đặt dấu ngoặc đơn quanh một cột sẽ không có sự khác biệt về hành vi của nó.

Nếu bạn muốn kết quả của bạn để chứa giá trị chỉ duy nhất của SG.GID, bạn có thể sử dụng một điều khoản GROUP BY thay - nhưng sau đó bạn phải quyết định một số quy tắc cho giá trị mà bạn muốn quay trở lại trong các cột khác. Bạn làm điều này bằng cách sử dụng chức năng tổng hợp như MIN(), MAX(), COUNT(), SUM() vv ví dụ đơn giản:

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; 

Khi tham gia nhiều bảng như trong truy vấn ban đầu của bạn, bạn phải cẩn thận khi đếm và tổng hợp mọi thứ, như các từ khóa trùng lặp có thể cung cấp cho bạn kết quả không chính xác.

Một lựa chọn khác là sử dụng ROW_NUMBER() trở về một hàng cho mỗi 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; 

số này các hàng cho mỗi SGID, bắt đầu từ 1 và được sắp xếp theo giá trị của SG.START_TIME. Nó sẽ trả về một hàng với thời gian bắt đầu sớm nhất cho mỗi SGID. Nếu nhiều hàng có cùng thời gian bắt đầu, nó sẽ chọn bất kỳ một trong số những hàng đó, nhiều hơn hoặc ít hơn một cách ngẫu nhiên. Bạn có thể thêm nhiều trường hơn vào mệnh đề ORDER BY để xác định thêm hàng nào được trả lại.

5

Vui lòng sử dụng mệnh đề GROUP BY khi DISTINCT không hoạt động cho kết quả mong muốn của bạn.

Các vấn đề liên quan