Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ORDER BY in CREATE VISTA

784 views
Skip to first unread message

Francesco

unread,
Jun 10, 2010, 5:22:48 AM6/10/10
to
Ciao a tutti, ho creato il comando che segue

CREATE VIEW Order
AS
SELECT OrderID,OrderDate, . . .
FROM Customers INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CompanyName

QUANDO lo eseguo mi visualizza il messaggio che segue:
Messaggio 1033, livello 15, stato 1, procedura Order, riga 6
La clausola ORDER BY non è consentita in viste, funzioni inline, tabelle
derivate, subquery ed espressioni di tabella comuni a meno che non sia
specificata anche la clausola TOP o FOR XML.

mentre se la creo da Management Studio non ci sono problemi.
Dove sbaglio?
grazie ciao


David Martin

unread,
Jun 10, 2010, 5:48:20 AM6/10/10
to
On 06/10/2010 11:22 AM, Francesco wrote:

> Dove sbaglio?

In una vista non bisogna usare la clausola ORDER BY, punto!

Se hai bisogno di risultati ordinati, aggiungerai la clausola ORDER BY
alla query che estrae i dati dalla vista:
SELECT campo1, campo2 FROM vista ORDER BY campo1


Ti sembrerà assurdo, ma se crei una vista come questa:
CREATE VIEW Order
AS
SELECT TOP 50 ord.OrderID, ord.OrderDate
FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
ORDER BY cus.CompanyName;

e poi estrai i dati con un'istruzione come questa:
SELECT OrderID, OrderDate FROM Order;

SQL Server non ti garantisce che i risultati siano ordinati... certo,
potresti essere fortunato e vederli ordinati, ma quello che devi capire
è che l'ordinamento non è garantito.

Perché? Perché in una vista la clausola ORDER BY serve solo ed
esclusivamente ad ordinare i dati per poi applicare la clausola TOP;
quindi determina *quali* dati saranno restituiti, ma non interviene nel
*come* i dati saranno restituiti.

--
David Martin

Marcello

unread,
Jun 10, 2010, 6:35:53 AM6/10/10
to
Il 10/06/2010 11:48, David Martin ha scritto:
> Ti sembrerà assurdo, ma se crei una vista come questa:
> e poi estrai i dati con un'istruzione come questa:
> SELECT OrderID, OrderDate FROM Order;
> SQL Server non ti garantisce che i risultati siano ordinati... certo,
> potresti essere fortunato e vederli ordinati, ma quello che devi capire
> è che l'ordinamento non è garantito.

Il problema è sostanzialmente di retrocompatibilità (e di lentezza di ms).
Volendo rivedere la sintassi in un'ottica moderna la query:

SELECT TOP 50 ord.OrderID, ord.OrderDate
FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
ORDER BY cus.CompanyName;

Dovrebbe estrarre 50 records (a caso) e ordinarli per cus.CompanyName.

SELECT TOP(50) over(order by cus.CompanyName), ord.OrderID, ord.OrderDate


FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID

Dovrebbe invece, e in modo disambiguo, estrarre i primi 50 records
secondo l'ordinamento cus.CompanyName e senza specifiche di ordinamento
sul resultset restituito.

Infine:

SELECT TOP(50) over(order by cus.CompanyName), ord.OrderID, ord.OrderDate


FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
ORDER BY cus.CompanyName;

Dovrebbe estrarre i primi 50 records secondo l'ordinamento
cus.CompanyName e ordinati secondo tale campo.

Non sarebbe di per sé nemmeno tanto complesso passare alla nuova
sintassi (e la clausola over per top è una delle più spinte da Itzik Ben
Gan), ma per retrocompatibilità l'uso ambiguo di "order by" alla fine di
una "select top" dovremo trascinarcelo ancora per moltissimo tempo.

marc.


Albe V°

unread,
Jun 10, 2010, 7:41:57 AM6/10/10
to
Francesco ha usato la sua tastiera per scrivere :

Una vista è sostanzialmente da usare come se fosse una tabella.
Quindi, così come una tabella non ha un ordinamento proprio ma devi
specificare tu l'ordine di estrazione (se ti serve un determinato
ordine), così in una vista sarà in fase di estrazione dalla vista che
dovrai specificare l'Order By, non all'interno della vista stessa.

Alberto


Andrea Montanari

unread,
Jun 10, 2010, 1:33:08 PM6/10/10
to
salve Marc.,

mm..
al di la' dell'aspetto semantico, che avrebbe sicuramente un senso,
imporrebbe un differenziale comunque interessante.. il fatto di dover prima
processare l'ORDER BY finale (che per definizione e' l'ultimo stage di una
proiezione, e Conor e' sistemico ed irremovibile su questo, ne discuteva
pochi giorni fa sulla mailing list privata MVP) per poi procedere in
definitiva al CROSS APPLY con il fork richiesto per il subset del nested
loop su Orders, in modo da poter discriminare a priori le righe di
cus.CustomerID = ord.CustomerID previste dal resultset finale...
diversamente il prodotto cartesiano della join potrebbe veramente essere
"ingombrante", come in effetti accade comunque a tutt'oggi, non credi? :)
saluti
--
Andrea Montanari (Microsoft MVP - SQL Server)
http://www.asql.biz
DbaMgr2k ver 0.21.1 - DbaMgr ver 0.65.1 and further SQL Tools
http://www.hotelsole.com - http://www.hotelsolericcione.de
--------- remove DMO to reply


Gigit

unread,
Jun 28, 2010, 8:50:20 AM6/28/10
to

> mm..
> al di la' dell'aspetto semantico, che avrebbe sicuramente un senso,
> imporrebbe un differenziale comunque interessante.. il fatto di dover
> prima processare l'ORDER BY finale (che per definizione e' l'ultimo stage
> di una proiezione, e Conor e' sistemico ed irremovibile su questo, ne
> discuteva pochi giorni fa sulla mailing list privata MVP) per poi
> procedere in definitiva al CROSS APPLY con il fork richiesto per il subset
> del nested loop su Orders, in modo da poter discriminare a priori le righe
> di cus.CustomerID = ord.CustomerID previste dal resultset finale...
> diversamente il prodotto cartesiano della join potrebbe veramente essere
> "ingombrante", come in effetti accade comunque a tutt'oggi, non credi? :)
> saluti
> --

Estiquaatsi dice "io letto attentamente parole di uomo bianco, ma
significato sfugge come salmone unto con olio di castoro"
:-)

Comunque, a parte gli scherzi, complimenti.


0 new messages