Kategorie szkoleń | Egzaminy | Kontakt
  • 3
  • 6
  • 152

Kwerenda:

select kolumna1 as kod, cast(kolumna_datetime as date) as data, sum(ilość) as suma from tabela group by kod, data

zwraca błąd - invalid column name 'kod'.

Jeśli napiszę group by kolumna1, cast(kolumna_datetime as date), wszystko działa prawidłowo.

Order by kod, data - również działa.

Co może powodować takie zachowanie?

Mateusz_Filipkowski
  • Zapytał
  • @ Mateusz_Filipkowski | 14.10.2014
    • laureat
    • 26
    • 2
    • 29

Odpowiedzi (3)

  • 4

Takie zachowanie jest intencjonalne. W dokumentacji klauzuli GroupBy dla T-SQL można przeczytać:
A column alias that is defined in the select list cannot be used to specify a grouping column.
Czyli nie można użyć aliasu zdefiniowanego w części select do określenia kolumny grupowania.

Dokumentacja Group By: http://technet.microsoft.com/en-US/library/ms177673%28v=sql.90%29.aspx

  • Odpowiedział
  • @ | 16.10.2014
  • TRENER ALTKOM AKADEMII
  • 1

Więcej klepaniny. A jest jakiś konkretny powód takiego ograniczenia?

Mateusz_Filipkowski
  • Odpowiedział
  • @ Mateusz_Filipkowski | 19.10.2014
    • laureat
    • 26
    • 2
    • 29
  • 12

Tak. Wynika to z logicznej kolejności przetwarzania zapytania TSQL, która jest inna od tej, w jakiej wpisujemy zapytanie.

 

Kolejność logiczna wygląda następująco:

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY

 

Widać z tego, że aliasy pól, które tworzymy w klauzuli SELECT, są dopiero dostępne dla ORDER BY. W związku z tym aliastów pól nie możemy stosować we wcześniejszych klauzulach.

 

To spore ograniczenie, które powoduje, że musimy kopiować kod, co w praktyce często prowadzi do błędów logicznych - wystarczy, że poprawimy wyrażenie w SELECT, a zapomnimy w GROUP BY. Błąd gotowy.

 

Problem ten można rozwiązać za pomocą podzapytania na podstawie innej tabeli (tzw. Derived Table):

 

select kod, data, sum(ilosc) 
from    
(select 
   kolumna1 as kod, 
   cast(kolumna_datetime as date) as data, 
   sum(ilosc) as suma 
from tabela) as q
group by kod, data

 

Można to napisać jeszcze wygodniej w postaci zapytania CTE (Common Table Expression):

 

with cte_query as 
(select 
   kolumna1 as kod, 
   cast(kolumna_datetime as date) as data, 
   sum(ilosc) as suma 
from tabela)

select kod, data, sum(ilosc) 
from cte_query
group by kod, data

 

Polecam takie rozwiązanie, zwłaszcza w przypadku złożonych wyrażeń obliczeniowych.

 

 

 

  • Odpowiedział
  • @ | 21.10.2014
  • TRENER ALTKOM AKADEMII