USE AdventureWorks2008R2;
GO
SELECT SalesOrderID, ProductID, OrderQty
,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Total'
,AVG(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Avg'
,COUNT(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Count'
,MIN(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Min'
,MAX(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Max'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664);
Czytałem o tej klauzuli i nie rozumiem, dlaczego jej potrzebuję. Co robi ta funkcja Over
? Co robi Partitioning By
? Dlaczego nie mogę wykonać zapytania podczas pisania Group By SalesOrderID
?
mysql
sql
sql-server
aggregate-functions
clause
WithFlyingColors
źródło
źródło
Odpowiedzi:
Państwo może używać
GROUP BY SalesOrderID
. Różnica polega na tym, że w przypadku GROUP BY można mieć tylko zagregowane wartości dla kolumn, które nie są uwzględnione w GROUP BY.W przeciwieństwie do tego, używając funkcji agregujących w oknie zamiast GROUP BY, można pobrać zarówno wartości zagregowane, jak i niezagregowane. Oznacza to, że chociaż nie robisz tego w swoim przykładowym zapytaniu, możesz pobrać zarówno pojedyncze
OrderQty
wartości, jak i ich sumy, liczebności, średnie itp. W grupach o tych samych wartościachSalesOrderID
.Oto praktyczny przykład, dlaczego kruszywa okienne są świetne. Załóżmy, że musisz obliczyć, jaki procent sumy stanowi każda wartość. Bez agregatów w oknie trzeba najpierw wyprowadzić listę zagregowanych wartości, a następnie połączyć ją z powrotem z oryginalnym zestawem wierszy, tj. W ten sposób:
Teraz spójrz, jak możesz zrobić to samo z agregatem okienkowym:
O wiele łatwiejsze i czystsze, prawda?
źródło
OVER
Klauzula jest potężny, że można mieć ponad agregaty różnych zakresach ( „okienkowych”), czy używaćGROUP BY
czy niePrzykład: uzyskaj liczbę na
SalesOrderID
i policz wszystkichZdobądź różne
COUNT
, nieGROUP BY
źródło
Gdybyś chciał tylko GRUPOWAĆ WEDŁUG SalesOrderID, nie byłbyś w stanie uwzględnić kolumn ProductID i OrderQty w klauzuli SELECT.
Klauzula PARTITION BY umożliwia rozbicie funkcji agregujących. Jednym z oczywistych i przydatnych przykładów byłoby wygenerowanie numerów linii dla linii zamówienia w zamówieniu:
(Moja składnia może się nieznacznie różnić)
Otrzymasz wtedy coś takiego:
źródło
Pozwól, że wyjaśnię na przykładzie, a będziesz mógł zobaczyć, jak to działa.
Zakładając, że masz następującą tabelę DIM_EQUIPMENT:
Uruchom poniżej SQL
Wynik byłby taki, jak poniżej
Zobacz, co się stało.
Możesz liczyć bez grupowania według YEAR i dopasować do ROW.
Kolejny interesujący SPOSÓB na uzyskanie tego samego wyniku, jeśli jak poniżej użycie klauzuli WITH, DZ działa jak VIEW in-line i może uprościć zapytanie, szczególnie złożone, co jednak nie ma miejsca w tym przypadku, ponieważ próbuję tylko pokazać użycie
źródło
Klauzula OVER w połączeniu z PARTITION BY stanowi, że poprzedzające wywołanie funkcji musi być wykonane analitycznie, oceniając zwrócone wiersze zapytania. Potraktuj to jako wbudowaną instrukcję GROUP BY.
OVER (PARTITION BY SalesOrderID)
stwierdza, że dla funkcji SUMA, ŚREDNIA, itd ..., zwraca wartość OVER podzbioru zwróconych rekordów z zapytania i PARTITION, który podzbiór według klucza obcego SalesOrderID.Zsumujemy więc każdy rekord OrderQty dla KAŻDEGO UNIQUE SalesOrderID, a ta nazwa kolumny będzie miała nazwę „Razem”.
Jest to O WIELE bardziej efektywny sposób niż korzystanie z wielu widoków wbudowanych w celu uzyskania tych samych informacji. Możesz umieścić to zapytanie w widoku wbudowanym i filtrować według sumy.
źródło
Query Petition
klauzulą.Podobnie jak w
Group By
klauzuliSkładnia:
funkcja (...) OVER (PARTITION BY col1 col3, ...)
Funkcje
COUNT()
,SUM()
,MIN()
,MAX()
, etcROW_NUMBER()
,RATION_TO_REOIRT()
etc.)Więcej informacji z przykładem: http://msdn.microsoft.com/en-us/library/ms189461.aspx
źródło
To wynik zapytania. Tabela używana jako źródło jest taka sama, z wyjątkiem tego, że nie ma ostatniej kolumny. Ta kolumna jest ruchomą sumą trzeciej.
Pytanie:
(tabela staje się publiczna.iuk)
To trochę ponad poziom dbase (1986), nie wiem, dlaczego potrzeba było ponad 25 lat, aby go dokończyć.
źródło