web-dev-qa-db-fra.com

Sélectionne plusieurs colonnes d'une table, mais groupe par une

Le nom de la table est "OrderDetails" et les colonnes sont indiquées ci-dessous:

OrderDetailID || ProductID || ProductName || OrderQuantity

J'essaie de sélectionner plusieurs colonnes et Group By ProductID avec SUM of OrderQuantity.

 Select ProductID,ProductName,OrderQuantity Sum(OrderQuantity)
 from OrderDetails Group By ProductID

Mais bien sûr, ce code donne une erreur. Je dois ajouter d’autres noms de colonnes à grouper, mais ce n’est pas ce que je veux et puisque mes données contiennent de nombreux éléments, donc les résultats sont inattendus de cette façon.

Exemple de requête de données:

ProductID, ProductName, OrderQuantity from OrderDetails

Les résultats sont ci-dessous:

 ProductID     ProductName    OrderQuantity
    1001          abc               5
    1002          abc               23    (ProductNames can be same)
    2002          xyz               8
    3004          ytp               15
    4001          aze               19
    1001          abc               7     (2nd row of same ProductID)

Résultat attendu:

 ProductID     ProductName    OrderQuantity
    1001          abc               12    (group by productID while summing)
    1002          abc               23
    2002          xyz               8
    3004          ytp               15
    4001          aze               19

Comment sélectionner plusieurs colonnes et la colonne Group By ProductID puisque ProductName n'est pas unique?

Ce faisant, obtenez également la somme de la colonne OrderQuantity.

34
Ozan Ayten

J'utilise cette astuce pour regrouper une colonne lorsque j'ai une sélection de plusieurs colonnes:

SELECT MAX(id) AS id,
    Nume,
    MAX(intrare) AS intrare,
    MAX(iesire) AS iesire,
    MAX(intrare-iesire) AS stoc,
    MAX(data) AS data
FROM Produse
GROUP BY Nume
ORDER BY Nume

Cela marche.

61
Urs Marian

Vos données

DECLARE @OrderDetails TABLE 
(ProductID INT,ProductName VARCHAR(10), OrderQuantity INT)

INSERT INTO @OrderDetails VALUES
(1001,'abc',5),(1002,'abc',23),(2002,'xyz',8),
(3004,'ytp',15),(4001,'aze',19),(1001,'abc',7)

Requête

 Select ProductID, ProductName, Sum(OrderQuantity) AS Total
 from @OrderDetails 
 Group By ProductID, ProductName  ORDER BY ProductID

Résultat

╔═══════════╦═════════════╦═══════╗
║ ProductID ║ ProductName ║ Total ║
╠═══════════╬═════════════╬═══════╣
║      1001 ║ abc         ║    12 ║
║      1002 ║ abc         ║    23 ║
║      2002 ║ xyz         ║     8 ║
║      3004 ║ ytp         ║    15 ║
║      4001 ║ aze         ║    19 ║
╚═══════════╩═════════════╩═══════╝
11
M.Ali

Vous pouvez essayer ceci:

Select ProductID,ProductName,Sum(OrderQuantity) 
 from OrderDetails Group By ProductID, ProductName

Vous ne devez utiliser que des colonnes Group By Qui ne viennent pas avec une fonction d'agrégat dans la clause Select. Vous pouvez donc simplement utiliser Group By ProductID et ProductName dans ce cas.

4
har07
    WITH CTE_SUM AS (
      SELECT ProductID, Sum(OrderQuantity) AS TotalOrderQuantity 
      FROM OrderDetails GROUP BY ProductID
    )
    SELECT DISTINCT OrderDetails.ProductID, OrderDetails.ProductName, OrderDetails.OrderQuantity,CTE_SUM.TotalOrderQuantity 
    FROM 
    OrderDetails INNER JOIN CTE_SUM 
    ON OrderDetails.ProductID = CTE_SUM.ProductID

S'il vous plaît vérifier si cela fonctionne.

2
Vikram

== EDIT ==

J'ai vérifié votre question à nouveau et ai conclu que cela ne pouvait pas être fait.

ProductName n'est pas unique, il doit faire partie du Group By ou exclus de vos résultats.

Par exemple, comment SQL vous présenterait-il ces résultats si vous Group By uniquement ProductID?

ProductID | ProductName | OrderQuantity 
---------------------------------------
1234      | abc         | 1
1234      | def         | 1
1234      | ghi         | 1
1234      | jkl         | 1
1
Joe_DM

Je voulais juste ajouter un moyen plus efficace et générique de résoudre ce genre de problèmes. L'idée principale est de travailler avec des sous-requêtes.

faites votre groupe par et rejoignez la même table sur l'ID de la table.

votre cas est plus spécifique puisque votre productId est non unique , il y a donc 2 façons de résoudre ce problème.

Je vais commencer par la solution la plus spécifique: Puisque votre productId est non unique , nous aurons besoin d’une étape supplémentaire qui consiste à sélectionner DISCTINCT product. les identifiants après le regroupement et la sous-requête comme suit:

WITH CTE_TEST AS (SELECT productId, SUM(OrderQuantity) Total
                    FROM OrderDetails
                    GROUP BY productId)
SELECT DISTINCT(OrderDetails.ProductID), OrderDetails.ProductName, CTE_TEST.Total
FROM OrderDetails 
INNER JOIN CTE_TEST ON CTE_TEST.ProductID = OrderDetails.ProductID

cela retourne exactement ce qui est attendu

 ProductID     ProductName         Total
    1001          abc               12    
    1002          abc               23
    2002          xyz               8
    3004          ytp               15
    4001          aze               19

Mais existe une méthode plus propre pour le faire. Je suppose que ProductId est une clé étrangère à la table des produits et je suppose qu'il devrait y avoir et OrderId clé primaire (unique) dans ce tableau.

dans ce cas, il y a peu d'étapes à faire pour inclure des colonnes supplémentaires lors du regroupement sur une seule. Ce sera la même solution que de suivre

Prenons ceci t_Value table par exemple:

enter image description here

Si je veux regrouper par description et également afficher toutes les colonnes.

Tout ce que je dois faire c'est:

  1. créer WITH CTE_Name sous-requête avec votre colonne GroupBy et la condition COUNT
  2. sélectionner tout (ou tout ce que vous voulez afficher) dans la table de valeurs et le total dans le CTE
  3. INNER JOIN avec CTE sur la colonne ID ( clé primaire ou contrainte unique)

et c'est tout!

Voici la requête

WITH CTE_TEST AS (SELECT Description, MAX(Id) specID, COUNT(Description) quantity 
                    FROM sch_dta.t_value
                    GROUP BY Description)
SELECT sch_dta.t_Value.*, CTE_TEST.quantity 
FROM sch_dta.t_Value 
INNER JOIN CTE_TEST ON CTE_TEST.specID = sch_dta.t_Value.Id

Et voici le résultat:

enter image description here

J'espère que cela t'aides!

HK

0
Haithem KAROUI

Vous pouvez essayer la requête ci-dessous. Je suppose que vous avez une seule table pour toutes vos données.

SELECT OD.ProductID, OD.ProductName, CalQ.OrderQuantity
FROM (SELECT DISTINCT ProductID, ProductName
      FROM OrderDetails) OD
INNER JOIN (SELECT ProductID, OrderQuantity SUM(OrderQuantity)
            FROM OrderDetails
            GROUP BY ProductID) CalQ
ON CalQ.ProductID = OD.ProductID
0
A_B

mysql GROUP_CONCAT La fonction pourrait aider https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_group-concat

SELECT ProductID, GROUP_CONCAT(DISTINCT ProductName) as Names, SUM(OrderQuantity)
FROM OrderDetails GROUP BY ProductID

Cela retournerait:

ProductID     Names          OrderQuantity
1001          red            5
1002          red,black      6
1003          orange         8
1004          black,orange   15

Idée similaire à celle @Urs Marian publiée ici https://stackoverflow.com/a/38779277/906265

0