2013-04-16 23 views
9

Próbuję uzyskać zamówienia od zamówienia. Moim zdaniem mam kilka wierszy z dokładnie tymi samymi wartościami, ale chcę pogrupować te wartości na orderid i pobrać sumę ilości tego zamówienia.Serwer SQL - GROUP BY w jednej kolumnie

moim zdaniem wyniki coś takiego:

Order_id Customer_id Article_id Delivery_date Quantity 
--------------------------------------------------------------------------- 
PR10.001 11   20.001a  17-04-2013  1 
PR10.001 11   20.001a  17-04-2013  1 
PR10.001 11   20.001a  17-04-2013  1 
PR13.001 15   41.022b  19-04-2013  1 
PR13.001 15   41.022b  19-04-2013  1 

chcę zrobić coś takiego:

SELECT Order_id, Customer_id Article_id, Delivery_date, sum(Quantity) 
FROM Orders 
GROUP BY Order_id 

Aby uzyskać coś takiego:

Order_id Customer_id Article_id Delivery_date Quantity 
--------------------------------------------------------------------------- 
PR10.001 11   20.001a  17-04-2013  3 
PR13.001 15   41.022b  19-04-2013  2 

Ale wiem grupowanie przez jednego pojedynczego kolumna nie jest możliwa, w przeciwnym razie pojawi się komunikat:

[...] jest nieprawidłowy na liście wyboru, ponieważ nie jest zawarty w ani funkcji agregującej, ani klauzuli GROUP BY.

Czy istnieje inna możliwość lub obejście do grupowania według jednej konkretnej kolumny w SQL Server?

+0

Przepraszam, coś było nie tak z moim przykładzie mam editted go, powinno być jasne, teraz – Jovano

Odpowiedz

14

można użyć CTE z SUM(Quantity)OVER(PARTITION BY Order_id) + ROW_NUMBER wyłowić żądany wiersz z rzędu-group:

WITH cte 
    AS (SELECT order_id, 
       customer_id, 
       article_id, 
       delivery_date, 
       quantity=Sum(quantity) 
          OVER( 
          partition BY order_id), 
       rn = Row_number() 
         OVER( 
         partition BY order_id 
         ORDER BY delivery_date ASC) 
     FROM orders) 
SELECT order_id, 
     customer_id, 
     article_id, 
     delivery_date, 
     quantity 
FROM cte 
WHERE rn = 1 

DEMO

jednak pożądany wynik wydaje się być niepoprawny (pytanie edytowany)

To jest mój wynik:

ORDER_ID CUSTOMER_ID ARTICLE_ID DELIVERY_DATE QUANTITY 
PR10.001 11   20.001a   17-04-2013 3 
PR13.001 15   41.022b   19-04-2013 2 
+0

Wygląda na to, że ARTICLE_ID może być wielokrotnością dla każdego ORDER_ID, w powyższej próbce CTE, która pierwsza została wybrana, nie jest kompletnym wynikiem. – harsh

+0

@harsh: OP nie wspomniał o tym, że chce także grupy po artykule, więc zostawiłem go takim, jaki jest. W przeciwnym razie mógłby po prostu dodać ARTICLE_ID do "PARTYCJI PRZEZ". –

+0

Po pierwsze: Tim ma rację, grupowanie według Article_id nie jest konieczne, ponieważ każde zamówienie ma tylko jeden rodzaj artykułu. Po drugie, co za okropne i skomplikowane podejście do pracy, tak jakbyś pracował z MySQL, gdzie można użyć tylko jednej grupy, ale działa teraz GREAT! Wszystkie kredyty dla ciebie, dzięki! – Jovano

10

Zakładając innych kolumn są funkcjonalnie zależne od kolumny grupowania, najprostsze odpowiedzi są albo

się. Grupa przez innych kolumn, a także:

SELECT Order_id, Customer_id, Article_id, Delivery_date, sum(Quantity) 
FROM Orders 
GROUP BY Order_id, Customer_id, Article_id, Delivery_date 

lub

b. Użyj łączną funkcję taką jak max:

SELECT Order_id, max(Customer_id), max(Article_id), max(Delivery_date), sum(Quantity) 
FROM Orders 
GROUP BY Order_id 

Moje osobiste preferencje to drugie podejście, ponieważ myślę, że jest jaśniejsza niż pierwsza w wskazujące, które elementy są rzeczywiście potrzebne do grupowania, w przeciwieństwie do którego są jedynie zgrupowane aby obejść problem z niezgrupowanymi/niezagregowanymi kolumnami.

+0

To była moja logika też, ale kiedy spróbuj zrobić nowy widok, otrzymuję nowe problemy: Przy pierwszym rozwiązaniu otrzymuję: "Nie można porównywać ani sortować tekstów, ntext i typów danych obrazu, z wyjątkiem użycia operatora IS NULL lub LIKE.", który powinien być spowodowane przez niektóre kolumny, których nie uwzględniłem w moim przykładzie. Twoja druga nie działa również dlatego, że mam kilka kolumn varchar, które nie obsługują max() – Jovano

+0

@JorikvanOnna: Spodziewam się, że kolumny varchar zawsze będą obsługiwały 'max', ale niekoniecznie tekstowe, ntext lub image typy danych. Ponieważ wydaje się, że jest to podstawowa przyczyna problemu, sugeruję zaktualizować pytanie, aby uwzględnić te informacje. Odpowiedź Tima powinna działać, nawet z tym ograniczeniem; innym podejściem byłoby grupowanie według kolumny grupowania i włączanie zagregowanej wartości do widoku śródliniowego/CTE, a następnie łączenie z innymi tabelami zawierającymi kolumny problemów - wymagałoby to więcej informacji w pytaniu. –

0

W twoim scenariuszu nie wydaje się poprawne grupowanie - przez Order_id o różnych Article_id. Oczekiwany wynik wydaje się błędny. Powinno być:

PR10.001 ma dwa id_artykulu 20.001a, 41.022b oraz całkowitą ilość 4 (nie 3)

Czy Twój oczekiwanie jest uzyskanie całkowitej ilości dla każdego ORDER_ID ale zachowując zmieniającą kolumnę za to trzeba decydować o oczekiwanym wyniku?coś takiego:

Order_id Customer_id Article_id   Delivery_date Quantity 
--------------------------------------------------------------------------- 
PR10.001 11   20.001a, 41.022b  17-04-2013  4 
PR13.001 15   41.022b    19-04-2013  2 
+0

mój oczekiwany wynik był rzeczywiście błędny, ale zredagowałem go, powinienem być teraz – Jovano

0

Użyłem podobnego rodzaju stołu jak twój. nazwy byłyby inne jsu, aby je szybko przetestować. Proszę odnieść się do następującego zapytania. Zmień nazwy według potrzeb.

select ordid,customerid,articleid,SUM(cast(quantity as numeric)) quantity from test_stack group by ordid,customerid,articleid 
0

Z CTE CO (SELECT order_id, customer_id, ARTICLE_ID, delivery_date, ilości = suma (ilość) NAD ( partycji poprzez ORDER_ID) RN = row_number() NAD ( partycja BY order_id ORDER BY delivery_date ASC) FROM orders) SELECT order_id, customer_id, article_id, delivery_date, ilość OD CTE WHERE rn = 1