2012-11-22 13 views
8

SQL skrypt, to być prowadzony bez problemu w serwerze produkcyjnym przez długi czas, Ale ostatnio „musi pojawić ORDER BY pozycji na liście select jeżeli oświadczenie zawiera operator UNION” Raport systemuCzy pozycje ORDER BY pojawiają się na liście wyboru, jeśli instrukcja zawiera operatora UNION?

to dziwne że skrypt sql nadal może działać na moim serwerze testowym. Więc nie wiem, czy jakakolwiek poprawka, którą wykonuję, może działać poprawnie w produkcji.

SELECT '' as value ,'Outstanding' as text , 0 as disp_order 
union 
select a.buyer_status_code AS value , a.buyer_status_name AS text ,a.disp_order 
FROM rfq_buyer_status_v a WITH (NOLOCK) 
ORDER BY a.disp_order 

Odpowiedz

15

spróbuj tego:

select * from 
(
SELECT '' as value ,'Outstanding' as text , 0 as disp_order 
union 
select a.buyer_status_code AS value , a.buyer_status_name AS text ,a.disp_order 
FROM rfq_buyer_status_v a WITH (NOLOCK) 
) t 

ORDER BY t.disp_order 
14

Serwer SQL analizuje zapytania w kolejności faz w następujący sposób:

OD -> Gdzie -> GROUP BY -> HAVING -> wybierz - > ZAMÓW przez

Każda faza działa na jednej lub wielu tabelach jako dane wejściowe i zwraca tabelę wirtualną jako dane wyjściowe. Tabela wyjściowa jednej fazy jest uważana za wejście do następnej fazy. Jest to zgodne z operacjami relacji, które dają relację. Jeśli określono ORDER BY, wynik NIE jest relacyjny.

Wszelkie aliasy zdefiniowane we wcześniejszej fazie można zobaczyć w kolejnych fazach, ale nie odwrotnie.

np.

następujące zapytanie jest w porządku

SELECT [Col_1], [Col_2] 
FROM Table_A AS A 
WHERE A.[Col_1] > 0 
ORDER BY A.[Col_2]; 

podczas gdy ten nie będzie działać

SELECT [Col_1] AS C1, [Col_2] AS C2 
FROM Table_A 
WHERE C1 > 0 
ORDER BY C2; 

Teraz operator zestaw UNION łączy rezultaty dwóch wejściowych zapytaniami. Jako operator zestawu, UNION ma domniemaną właściwość DISTINCT, co oznacza, że ​​nie zwraca on duplikatów wierszy.

Jeśli użyłeś UNION w zapytaniu, połączyłeś te dwa zestawy w jeden, a ORDER BY zacznie obowiązywać w połączonym zbiorze, nie tylko w zbiorze danych SELECT ... FROM .... Powodem jest to, że ORDER BY jest najsłabszym (lub ostatnim) w kolejce, a "Catches All"

W pierwszym wierszu zapytania podałeś 0 alias o nazwie "disp_order", to jest w porządku. po operatorze UNION zapytanie o zbiór danych z tabeli "rfq_buyer_status_v", które zawiera kolumnę o nazwie "disp_order", również jest do przyjęcia. Problem pojawia się po ORDER BY.

Tak jak podałeś tabelę, alias, a mianowicie "a", ORDER BY aispisp_order oznacza ograniczenie akcji porządkowania częściowego zbioru danych, co jest w konflikcie z działaniem "Zlecenia wszystkich".

Rozwiązaniem byłoby usunięcie "a". po klauzuli ORDER BY. Powodem, dla którego możesz to zrobić w ten sposób, jest podanie aliasu "disp_order", który jest taki sam jak nazwa kolumny z tabeli rfq_buyer_status_v. Cóż, w tym przypadku nie widziałem żadnej wartości aliasowania stołu ...

SELECT '' AS value ,'Outstanding' AS text , 0 AS disp_order 
UNION 
SELECT a.buyer_status_code AS value , a.buyer_status_name AS text ,a.disp_order 
FROM rfq_buyer_status_v a WITH (NOLOCK) 
ORDER BY disp_order 

Alternatywnym sposobem pisania zapytania jest

SELECT ''   AS value , 
     'Outstanding' AS text , 
     0    AS ABC 
UNION 
SELECT buyer_status_code AS value , 
     buyer_status_name AS text , 
     disp_order  AS ABC 
FROM rfq_buyer_status_v 
    WITH (NOLOCK) 
ORDER BY ABC 

Drugi dał kolumnie disp_order zupełnie inny alias i stało się łatwe do odczytania i zmniejszone szanse na uzyskanie mylić podczas przeglądu kodu.

Powiązane problemy