2012-03-13 20 views
16

Tôi có một truy vấn CTE lọc một sinh viên bảngNhiều Chọn đối với một CTE

Student 

    (
    StudentId PK, 
    FirstName , 
    LastName, 
    GenderId, 
    ExperienceId, 
    NationalityId, 
    CityId 
) 

Dựa trên một bộ lọc rất nhiều (nhiều thành phố, giới tính, nhiều kinh nghiệm (1, 2, 3), nhiều nationalites), tôi tạo ra một CTE bằng cách sử dụng sql năng động và tham gia vào bảng sinh viên với một người dùng định nghĩa bảng (CityTable, NationalityTable,...)

Sau đó tôi phải lấy số lượng học sinh theo từng bộ lọc như

CityId City Count 

NationalityId Nationality Count 

Điều tương tự với bộ lọc khác.

Tôi có thể làm điều gì đó như

;With CTE(
     Select 
     FROM Student 
     Inner JOIN ... 
     INNER JOIN ....) 
    SELECT CityId,City,Count(studentId) 
    FROm CTE 
    GROUP BY CityId,City 

    SELECT GenderId,Gender,Count 
    FROM CTE 
    GROUP BY GenderId,Gender 

Tôi muốn một cái gì đó giống như những gì LinkedIn đang làm với tìm kiếm (mọi người tìm kiếm, tìm kiếm việc làm)

http://www.linkedin.com/search/fpsearch?type=people&keywords=sales+manager&pplSearchOrigin=GLHD&pageKey=member-home

Đó là quá nhanh và làm tương tự Điều.

+4

NO. CTE chỉ hợp lệ ** cho câu lệnh tiếp theo (đơn) **. Nếu bạn cần "bảo toàn" dữ liệu, bạn cần phải đặt nó vào một ví dụ bảng biến hoặc bảng tạm thời. –

+0

Đó là những gì tôi đã làm. Pb là tôi lọc bảng để chỉ hiển thị ở cuối chỉ 20 hàng trong một DataGrid (top 21) + nhóm by.it chậm với nhiều phép nối. –

Trả lời

12

Bạn không thể sử dụng nhiều lựa chọn nhưng bạn có thể sử dụng nhiều CTE như thế này.

WITH CTEA 
AS 
(
SELECT 'Coulmn1' A,'Coulmn2' B 
), 
CETB 
AS 
(
SELECT 'CoulmnX' X,'CoulmnY' Y 
) 

SELECT * FROM CTEA, CETB 

Để sử dụng đếm, RowNumber và CTE một số nghĩ như thế này.

ROW_NUMBER() OVER (ORDER BY COLUMN NAME)AS RowNumber, 
Count(1) OVER() AS TotalRecordsFound 

Vui lòng cho tôi biết nếu bạn cần thêm thông tin về điều này.

Mẫu để bạn tham khảo.

With CTE AS (
     Select StudentId, S.CityId, S.GenderId 
     FROM Student S 
     Inner JOIN CITY C 
     ON S.CityId = C.CityId 
     INNER JOIN GENDER G 
     ON S.GenderId = G.GenderId) 
, 
GENDER 
AS 
(
    SELECT GenderId 
    FROM CTE 
    GROUP BY GenderId 
) 


SELECT * FROM GENDER, CTE 
+0

Nếu bạn đăng mã, XML hoặc mẫu dữ liệu, ** XIN VUI LÒNG ** làm nổi bật những dòng đó trong trình soạn thảo văn bản và nhấp vào nút "mẫu mã" ('{}') trên thanh công cụ trình soạn thảo để định dạng và cú pháp tô sáng nó! –

+0

OKi.kết quả mã của bạn hiển thị cùng số hàng cho cte và nhóm by.I muốn tách chúng ra. –

+0

Bạn có thể làm một cái gì đó như thế này trong một 'VIEW'? Tôi đã cố gắng và có một lỗi cú pháp. Tôi nghĩ bạn bị giới hạn chỉ một CTE cho mỗi lượt xem. –

8

Không thể nhận nhiều tập hợp kết quả từ một CTE duy nhất. Tuy nhiên bạn có thể sử dụng một biến bảng để cache một số thông tin và sử dụng nó sau này thay vì phát hành cùng truy vấn phức tạp nhiều lần:

declare @relevantStudent table (StudentID int); 

insert into @relevantStudent 
select s.StudentID from Students s 
join ... 
where ... 

-- now issue the multiple queries 

select s.GenderID, count(*) 
from student s 
join @relevantStudent r on r.StudentID = s.StudentID 
group by s.GenderID 

select s.CityID, count(*) 
from student s 
join @relevantStudent r on r.StudentID = s.StudentID 
group by s.CityID 

Bí quyết là để lưu trữ chỉ là thông tin cần thiết tối thiểu trong biến bảng. Cũng giống như bất kỳ truy vấn nào cho dù điều này thực sự sẽ cải thiện hiệu suất so với việc phát hành truy vấn độc lập phụ thuộc vào nhiều thứ (mức độ lớn của tập dữ liệu biến bảng, truy vấn được sử dụng phức tạp như thế nào và phức tạp như thế nào so với biến bảng, v.v.)

+0

Rất tiếc, điều này sẽ không hoạt động với chế độ xem. – MgSam

3

Thực hiện UNION ALL để thực hiện nhiều SELECT và nối các kết quả lại với nhau thành một bảng.

;WITH CTE AS(
     SELECT 
     FROM Student 
     INNER JOIN ... 
     INNER JOIN ....) 
    SELECT CityId,City,Count(studentId),NULL,NULL 
     FROM CTE 
     GROUP BY CityId,City 
    UNION ALL 
    SELECT NULL,NULL,NULL,GenderId,Gender,Count 
     FROM CTE 
     GROUP BY GenderId,Gender 

Lưu ý: Giá trị NULL ở trên chỉ cho phép hai kết quả có cột phù hợp, do đó kết quả có thể được ghép nối.

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