web-dev-qa-db-fra.com

SQL Server - GROUP BY sur une colonne

J'essaie d'obtenir des ordres d'un ordre. À mon avis, certaines lignes contiennent exactement les mêmes valeurs, mais je souhaite regrouper ces valeurs sur orderid et prendre la somme de la quantité de cette commande.

Ma vue résulte quelque chose comme:

 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

Je veux faire quelque chose comme:

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

Pour obtenir quelque chose comme:

 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

Mais je sais que le regroupement en une seule colonne n’est pas possible, sinon vous obtiendrez le message suivant:

[...] est invalide dans la liste de sélection car il n'est pas contenu dans soit une fonction d'agrégat, soit la clause GROUP BY.

Existe-t-il une autre possibilité ou solution de contournement de regrouper une colonne spécifique dans SQL Server?

11
Jovano

Vous pouvez utiliser une CTE avec SUM(Quantity)OVER(PARTITION BY Order_id) + ROW_NUMBER pour choisir la ligne souhaitée dans le groupe de commandes:

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 

DÉMO

Cependant, votre résultat souhaité semble être incorrect (question modifiée)

Ceci est mon résultat:

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
17
Rango

En supposant que les autres colonnes sont fonctionnellement dépendantes de la colonne de regroupement, les réponses les plus simples sont soit

une. Regrouper aussi par les autres colonnes:

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

ou 

b. Utilisez une fonction d'agrégation telle que max:

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

Ma préférence personnelle est la deuxième approche, car je pense qu’elle est plus claire que la première en indiquant quels éléments sont réellement requis pour le regroupement, par opposition à ceux qui sont simplement regroupés pour résoudre le problème des colonnes non groupées/non agrégées.

9
user359040

Dans votre scénario, il ne semble pas correct de grouper par Order_id en faisant varier Article_id. Vous attendez le résultat semble faux. CA devrait etre:

PR10.001 a deux Article_id 20.001a, 41.022b et la quantité totale 4 (pas 3)

Vous attendez-vous à obtenir la quantité totale pour chaque Order_id tout en conservant des colonnes variables, vous devez donc décider du résultat attendu? quelque chose comme:

 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
harsh

AVEC cte AS (SELECT order_id, Customer_id, Article_id, Delivery_date, Quantité = Sum (quantité) OVER ( Partition BY order_id), Rn = Row_number () OVER ( Partition BY order_id ORDER BY delivery_date ASC) FROM ordres) SELECT order_id, N ° de client, article_id, date de livraison, quantité DE cte WHERE rn = 1 

0
Nani

J'ai utilisé le même type de table que la tienne. les noms seraient différents jsu pour le tester rapidement ..___ Veuillez vous référer à la requête suivante Modifiez les noms selon vos besoins.

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