Travis
Travis

Reputation: 669

Using GROUP_CONCAT on an already GROUPed query in MySQL

I have a large order list that I need to create, and I need to get a list of product codes and their quantities on a per order basis.

To simplify, I'm showing an example for a single order, but the outer query will need to provide this result for every order in the system.

So far, I have the following:

mysql> select ProductCode,Quantity from OrderProducts where Order_ID = X;
+-------------+----------+
| ProductCode | Quantity |
+-------------+----------+
| PROD1       |        1 |
| PROD2       |        1 |
| PROD1       |        1 |
+-------------+----------+
3 rows in set (0.00 sec)

mysql> SELECT CONCAT(OrderProducts.ProductCode,' (',SUM(OrderProducts.Quantity),')') FROM OrderProducts WHERE Order_ID = X GROUP BY OrderProducts.ProductCode;
+------------------------------------------------------------------------+
| CONCAT(OrderProducts.ProductCode,' (',SUM(OrderProducts.Quantity),')') |
+------------------------------------------------------------------------+
| PROD1 (2)                                                              |
| PROD2 (1)                                                              |
+------------------------------------------------------------------------+
2 rows in set (0.00 sec)

What I need is a GROUP_CONCAT result of the query above,but it won't let me wrap a GROUP_CONCAT around the CONCAT shown above because I think because the SUM() is already doing grouping itself. Here is what I need to get back:

PROD1 (2),PROD2 (1)

EDIT

I was unclear about the use of the query above. I will be using that query as a subquery within a select which will be querying on ALL orders in Orders. Below is an updated version of the query:

SELECT 
  ( 
    SELECT 
      GROUP_CONCAT(SerialNumberedProductCount) 
    FROM  
    ( 
      SELECT 
        OrderProducts.Order_ID,
        CONCAT(OrderProducts.ProductCode,' (',SUM(OrderProducts.Quantity),')') AS SerialNumberedProductCount 
       FROM  
        OrderProducts, Products 
       WHERE 
        OrderProducts.Order_ID = Orders.Order_ID AND 
        OrderProducts.Product_ID = Products.Product_ID AND 
        Products.IsSerialNumbered = 1 
       GROUP BY 
        OrderProducts.ProductCode
    ) SerialNumberedProductCountsSubQuery 
    WHERE 
      SerialNumberedProductCountsSubQuery.Order_ID = Orders.Order_ID
  ) AS SerialNumberedProductCounts 
FROM 
  Orders

With the above query, I am getting the following error:

ERROR 1054 (42S22): Unknown column 'Orders.Order_ID' in 'where clause'

Upvotes: 2

Views: 368

Answers (3)

Michael Berkowski
Michael Berkowski

Reputation: 270609

To apply another aggregate, you will need to wrap it in a subquery. This will apply the aggregate GROUP_CONCAT() over all rows returned by the subquery though, as is the output from your desired example. Since the inner subquery only returns the one already aggregated column, there is no need for a GROUP BY in the outer query

SELECT GROUP_CONCAT(prod_sum)
FROM (
  SELECT CONCAT(OrderProducts.ProductCode,' (',SUM(OrderProducts.Quantity),')') AS prod_sum 
  FROM OrderProducts 
  WHERE Order_ID = 'X'
  GROUP BY OrderProducts.ProductCode
) subq

http://sqlfiddle.com/#!2/68bca/4

Update after re-post

To join the results of your subqueries against Orders, you probably ought to be joining this entire construct in instead of using a subselect.

SELECT 
  /* Replace these with the columns you actually need */
  Orders.*,
  SerialNumberedProductCounts.*
FROM 
  Orders
  LEFT JOIN ( 
    SELECT
      Order_ID, 
      GROUP_CONCAT(SerialNumberedProductCount) 
    FROM  
    ( 
      SELECT 
        OrderProducts.Order_ID,
        CONCAT(OrderProducts.ProductCode,' (',SUM(OrderProducts.Quantity),')') AS SerialNumberedProductCount 
       FROM  
        OrderProducts, Products 
       WHERE 
        OrderProducts.Product_ID = Products.Product_ID AND 
        Products.IsSerialNumbered = 1 
       GROUP BY 
        OrderProducts.ProductCode
    ) SerialNumberedProductCountsSubQuery 
    GROUP BY Order_Id
  ) AS SerialNumberedProductCounts 
  ON SerialNumberedProductCounts.Order_ID = Orders.Order_ID

Upvotes: 2

Strawberry
Strawberry

Reputation: 33935

SELECT GROUP_CONCAT(CONCAT(productcode,'(',n,')')) summary 
  FROM 
     ( SELECT productcode
            , SUM(quantity) n 
         FROM orderproducts 
        WHERE order_id = x
        GROUP 
           BY productcode
     ) x;

Upvotes: 1

Muhammad Raheel
Muhammad Raheel

Reputation: 19882

You can use it like this

SELECT
  GROUP_CONCAT(con) as Con
from (SELECT
    CONCAT(OrderProducts.ProductCode,' (',SUM(OrderProducts.Quantity),')') as Con
      FROM OrderProducts
      WHERE Order_ID = X
      GROUP BY OrderProducts.ProductCode
) as r

Upvotes: 1

Related Questions