2014-09-10 33 views
10

Przepraszam, jeśli to duplikat, ale go nie znalazłem. Dlaczego nie mogę użyć mojego aliasu kolumny zdefiniowanego w SELECT z ORDER BY, kiedy używam CASE?Dlaczego nie mogę odwołać się do aliasu kolumny w ZAMÓWIENIU, używając CASE?

Rozważmy proste zapytanie:

SELECT NewValue=CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END 
FROM dbo.TableA 
ORDER BY CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END 

wynik jest błąd:

Invalid column name 'NewValue'

Here's a sql-fiddle. (Wymień ORDER BY NewValue z CASE WHEN... that' w komentarzu)

wiem mogę użyć ORDER BY CASE WHEN Value IS NULL THEN 1 ELSE 0 END jak here w tym przypadku, ale w rzeczywistości zapytanie jest bardziej złożone i t, aby było to tak czytelne, jak to tylko możliwe. Czy zamiast tego muszę użyć sub-zapytania lub CTE, jeśli tak, dlaczego tak jest?

Aktualizacja Mikael Eriksson komentuje każdy ekspresję w połączeniu z aliasu nie jest dozwolone. Więc nawet to (zapytanie bezcelowe) nie z tego samego powodu:

SELECT '' As Empty 
FROM dbo.TableA 
ORDER BY Empty + '' 

Wynik:

Invalid column name 'Empty'.

więc aliasem jest dozwolone w ORDER BY a także wyrazem ale nie oba. Dlaczego, jest zbyt trudne do wdrożenia? Ponieważ jestem głównie programistą, myślę o aliasach jako zmiennych, które można by łatwo wykorzystać w wyrażeniu.

+0

Dlaczego nie zawijać warunek sprawy w zewnętrznym zastosowaniu i porządku przez to pole? –

+1

@AndyKorneyev: Wiem też, jakie są tego rozwiązania, ale zastanawiałem się, dlaczego to nie jest dozwolone. Wydaje się, że jest to dość powszechne i pseudonim ma ukrywać złożoność, więc dlaczego nie mogę tego zrobić, jeśli mogę normalnie używać aliasów w "ORDER BY"? –

+0

Jest tu długa dyskusja (może nieco nieaktualna): http://social.msdn.microsoft.com/Forums/sqlserver/en-US/4ad14cad-1e61-43a0-96f8-70a506106a00/column-alias-usage -wszyscy-w-zapytanie-po-definicja-forum? forum = transactsql – davek

Odpowiedz

5

ma to związek z tym, jak DBMS SQL rozwiązuje nazwy wieloznaczne.

Nie wykryłem jeszcze tego zachowania w standardach SQL, ale wydaje się, że jest ono spójne na różnych platformach. Oto co się dzieje.

Alias ​​"col_1" jako "col_2" i użyj aliasu w klauzuli ORDER BY. DBMS rozpoznaje "col_2" w ORDER BY jako alias dla "col_1" i sortuje według wartości w "test". "Col_1".

select col_1 as col_2 
from test 
order by col_2; 
 
col_2 
-- 
1 
2 
3 

Ponownie, alias "col_1" jako "col_2", ale użyć wyrażenia w klauzuli ORDER BY. DBMS rozwiązuje "col_2" nie jako alias dla "col_1", ale jako kolumnę "test". "Col_2". Sortuje według wartości w "teście". "Col_2".

select col_1 as col_2 
from test 
order by (col_2 || ''); 
 
col_2 
-- 
3 
2 
1 

Więc w twoim przypadku, zapytanie nie powiedzie się, ponieważ DBMS chce rozwiązać „nowaWartość” w wyrażeniu jako nazwa kolumny w tabeli bazowej. Ale nie jest; to jest alias kolumnowy.

PostgreSQL

Zachowanie to udokumentowano w PostgreSQL w sekcji Sorting Rows. Ich uzasadnieniem jest zmniejszenie niejednoznaczności.

Note that an output column name has to stand alone, that is, it cannot be used in an expression — for example, this is not correct:

SELECT a + b AS sum, c FROM table1 ORDER BY sum + c;   -- wrong 

This restriction is made to reduce ambiguity. There is still ambiguity if an ORDER BY item is a simple name that could match either an output column name or a column from the table expression. The output column is used in such cases. This would only cause confusion if you use AS to rename an output column to match some other table column's name.

błąd w dokumentacji SQL Server 2008

nieznacznie inny problem w odniesieniu do aliases in the ORDER BY clause.

If column names are aliased in the SELECT list, only the alias name can be used in the ORDER BY clause.

O ile nie mam zbyt małej ilości kofeiny, nie jest to prawdą. Ta instrukcja jest sortowana według "testu". "Col_1" w obu SQL Server 2008 i SQL Server 2012.

select col_1 as col_2 
from test 
order by col_1; 
+0

Dzięki (+). Pozostaje jednak pytanie: dlaczego tak jest? Dlaczego mogę używać wyrażenia w order_by, a także w aliasie, ale nie w obu jednocześnie? DBMS może sprawdzić, czy istnieje alias "NewValue", jeśli tak, to wziąć w innym przypadku dostępną kolumnę o tej nazwie. Btw, 'order by (col_2 + '');' jest naprawdę dziwne, ponieważ działa. Używa kolumny 'col_2' zamiast aliasu. –

+0

Nie wiem jeszcze, dlaczego tak się dzieje. Spodziewam się znaleźć coś w standardach SQL, ale to zajmuje mi trochę czasu nawet w najlepszych okolicznościach. –

+0

Re: Błąd dokumentacji w SQL Server 2008 - może po prostu nie udało się umieścić poprawnego nacisku, może chcieli powiedzieć, że jeśli do sortowania zestawu wyników używany jest alias, powinien on być tylko aliasem (w przeciwieństwie do wyrażenia używając aliasu). Całkiem dziko, zgadnij. –

-1

Można spróbować czegoś takiego:

select NewValue from (
    SELECT (CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END) as NewValue, 
    (CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END) as ValOrder 
    FROM dbo.TableA 
    GROUP BY Value 
) t 
ORDER BY ValOrder 
+0

Dzięki. Ale jak już wspomniałem, znam obejścia takie jak sub-zapytania lub CTE, aby odsłonić tę kolumnę i używać jej w dowolnym miejscu (nawet w "WHERE"). Ale pytanie brzmi, dlaczego muszę dodać złożoność (która jest z pewnością sublicencją), aby zrobić coś, co [powinno być dozwolone w "ZAMÓWIENIU"] (http://msdn.microsoft.com/en-us/library /ms188385.aspx)(_"**order_by_expression**: Służy do określania kolumna lub wyrażenie do sortowania zestawu wyników kwerendy.W kolumnie sortowania można podać nazwę ** lub alias kolumny ** lub nieujemną liczbę całkowitą reprezentujący pozycję kolumny na liście wyboru "_). –