2012-03-13 18 views
16

Mam kwerendy CTE filtrowania Student stołowegoMultiple Wybierz przeciwko jednemu CTE

Student 

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

oparty na filtrach partii (kilka miast, płci, wiele doświadczeń (1, 2, 3), wiele narodowości), I utworzyć CTE za pomocą dynamicznego SQL i łączenia tabeli Student z zdefiniowane przez użytkownika tabelach a (CityTable, NationalityTable,...)

potem muszę pobrać liczby studenta przez każdego filtra jak

CityId City Count 

NationalityId Nationality Count 

To samo dotyczy drugiego filtra.

Czy mogę zrobić coś

;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 

Chcę coś podobnego co LinkedIn robi z wyszukiwania (wyszukiwanie osób, poszukiwanie pracy)

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

To tak szybko i tak samo rzecz.

+4

NIE. CTE jest ważny tylko ** dla następnego (pojedynczego) wyciągu **. Jeśli chcesz "zachować" dane, musisz umieścić je w pliku np. tabela zmiennych lub temp.. –

+0

To właśnie robię. Pb jest to, że filtruję tabelę tak, aby wyświetlała się tylko na końcu tylko 20 wierszy w datagrid (u góry 21) + grupa by.it jest powolna z wieloma złączeniami. –

Odpowiedz

12

Nie można użyć wielokrotnego wyboru, ale można użyć więcej niż jednego CTE w ten sposób.

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

SELECT * FROM CTEA, CETB 

Aby uzyskać zliczanie, użyj RowNumber i CTE, niektórzy myślą tak.

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

Proszę dać mi znać, jeśli potrzebujesz więcej informacji na ten temat.

Próbka w celach informacyjnych.

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

Jeśli opublikujesz kod, XML lub próbki danych, ** PLEASE ** podświetl te linie w edytorze tekstu i kliknij przycisk "próbki kodu" ('{}') na pasku narzędzi edytora, aby ładnie sformatować i podświetlić składnię! –

+0

OK. Wynik twojego kodu pokazuje ten sam numer wiersza dla cte i grupy przez. Chcę je rozdzielić. –

+0

Czy możesz zrobić coś takiego w 'VIEW'? Próbowałem i dostałem błąd składni. Myślę, że jesteś ograniczony do tylko jednego CTE na widok. –

8

Nie jest możliwe uzyskanie wielu zestawów wyników z jednego CTE. Można jednak użyć zmiennej tabeli buforować niektóre informacje i używać go później zamiast wydawania samego kompleksu zapytania wielokrotnie:

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 

Sztuką jest, aby przechowywać tylko minimalną wymaganą informację w zmiennej tabeli.
Podobnie jak w przypadku każdego zapytania, czy to rzeczywiście poprawi wydajność w porównaniu do samodzielnego wystawiania zapytań, zależy od wielu rzeczy (jak duży jest zestaw danych zmiennych tabeli, jak złożone jest zapytanie użyte do zapełnienia i jak złożone są kolejne sprzężenia/subselekty względem zmiennej tabeli itp.).

+0

Niestety to nie zadziała z widokiem. – MgSam

3

Wykonaj numer UNION ALL, aby wykonać wielokrotne połączenie SELECT i połączyć wyniki w jedną tabelę.

;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 

Uwaga: Wartości NULL Powyższe tylko pozwalają mieć dwa wyniki pasujące kolumn, więc wyniki mogą być łączone.