2013-08-06 16 views
5

Poniżej moja druga sprawa nie działa, ponieważ odwołuję się do nazwy z podzapytania. Jakie jest dobre rozwiązanie tego problemu? Ponadto deklaruję parametr SortBy ... po prostu nie uwzględniłem tego w przykładzie. Dziękuję bardzo za pomoc!Serwer SQL - porządek według nazwy z podkwerendy

SELECT 
a.[PostID] 
,a.[Title] 
,a.[Date_Created] 
,(SELECT COUNT(VoteID) AS VoteCount 
    FROM [VoteTable] WHERE [PostID] = a.[PostID]) AS VoteCount 

FROM [PostTable] a 
INNER JOIN [Users] b 
ON a.Created_UserID = b.UserID 
WHERE a.Approved = 1 

ORDER BY 
CASE @SortBy 
    WHEN 1 THEN a.[Date_Created] END DESC, 
CASE @SortBy 
    WHEN 2 THEN [VoteCount] END DESC 
+0

Podaje mi niepoprawną nazwę kolumny. SQL Server 2008 – user1447679

Odpowiedz

1

wymienić:

WHEN 2 THEN [VoteCount] END DESC 

gdzie:

WHEN 2 THEN (SELECT COUNT(VoteID) AS VoteCount 
FROM [VoteTable] WHERE [PostID] = a.[PostID]) END DESC 
+0

To faktycznie działa ... Czy w ogóle przykład Kcodera powinien być zmodyfikowany? Nie otrzymuję żadnych błędów. Kliknij, aby kliknąć ten piękny znacznik wyboru! – user1447679

+0

@MichaelFredrickson Tak, wydaje się, że działa. Nadal testuję. – user1447679

+0

@MichaelFredrickson Koryguję się wtedy. Sądzę, że jest coś w tej szczególnej składni, która powoduje pęknięcie aliasu kolumny. – Kcoder

2

Powtarzanie tego wyrażenia jest w jedną stronę, jak to jest umieszczenie w podkwerendzie lub CTE, np

;WITH cte AS 
(
    SELECT 
    a.PostID 
    ,a.Title 
    ,a.Date_Created 
    ,(SELECT COUNT(VoteID) 
    FROM VoteTable WHERE PostID = a.PostID) AS VoteCount 
    FROM dbo.PostTable AS a 
    INNER JOIN dbo.Users AS b 
    ON a.Created_UserID = b.UserID 
    WHERE a.Approved = 1 
) 
SELECT PostID, Title, Date_Created, VoteCount 
FROM cte 
ORDER BY 
    CASE @SortBy 
    WHEN 1 THEN Date_Created END DESC, 
    CASE @SortBy 
    WHEN 2 THEN VoteCount END DESC; 

Zamiast powtarzać wyrażenie, to nie wydaje się mieć znaczenia, jeśli naprawdę wykonasz warunkowe dla drugiego rzędu przez. Więc dlaczego nie po prostu zmienić istniejący ORDER BY do:

ORDER BY CASE WHEN @SortBy = 1 THEN a.Date_Created END DESC, 
     VoteCount DESC; 

W tym przypadku, jeśli @SortBy wynosi 2, pierwszy wyraz jest NULL, a więc pożądany Zamawiający nadal osiągnięty. Gdy @SortBy ma wartość 1, jest uporządkowane według daty malejącej, a jeśli nie ma zbyt wielu powiązań z Date_Created, a w tym przypadku , nie chcesz zobaczyć te powiązania posortowane według VoteCount DESC, kolejność drugorzędna jest nieistotna, więc nie musisz Trzeba go zawinąć w drugim wyrażeniu CASE.

Powodem, nawiasem mówiąc, jest to, że kiedy wprowadzić wyrażenie CASE do ORDER BY, należy zmienić sposób SQL Server może analizować/oceny zapytania i nie można już odwołać alias z listy SELECT. Właśnie dlatego usunięcie klauzuli CASE z klauzuli ORDER BY nie powoduje już narzekania na niepoprawną nazwę kolumny.

0
SELECT 
a.[PostID] 
,a.[Title] 
,a.[Date_Created] 
,V.VoteCount 
FROM [PostTable] a 
INNER JOIN (SELECT PostID, COUNT(VoteID) AS VoteCount GROUP BY PostID) V 
    ON V.[PostID] = a.[PostID] 
INNER JOIN [Users] b 
ON a.Created_UserID = b.UserID 
WHERE a.Approved = 1 
ORDER BY 
CASE @SortBy 
    WHEN 1 THEN a.[Date_Created] END DESC, 
CASE @SortBy 
    WHEN 2 THEN V.[VoteCount] END DESC