0

I have the following query which lists orders along with items ordered.

select 
    `orders`.*, 
    DATE_FORMAT(orders.created_at, '%d.%m.%Y %h:%i%p') as date, 
    `oi`.`items` 
        from `orders` 
    inner join 
        (
            select 
                order_id,
                count(item_name) as count,
                group_concat(item_name SEPARATOR ",") as items 
                    from orders_items 
                    group by order_id
        ) 
    as oi on `oi`.`order_id` = `orders`.`id`

My tables are setup like so:

orders

id
1
2
3

orders_items

id    order_id    item_name
1     1           Class Voucher
2     1           Class Voucher
3     1           Class Voucher
4     1           The Cook Book

In the current query, the items column looks something like this when I output it:

Class Voucher,Class Voucher,Class Voucher,The Cook Book

How can I alter it so that each item has a count next to it, instead of listing out each item name. So I want items to contain this instead:

3 x Class Voucher
1 x The Cook Book

Thanks in advance.

2
  • query needs to be adjusted to exclude orders.created_at ( this is not currently part of your posted structure ) Commented Sep 11, 2015 at 9:26
  • FYI, you should use COUNT(*) unless you need to exclude null values from the count (this mostly comes up when counting rows in a LEFT JOIN). Commented Sep 11, 2015 at 9:31

2 Answers 2

2

You get there in two steps: First count the items, then get all items with their count per order:

select 
  orders.*, 
  DATE_FORMAT(orders.created_at, '%d.%m.%Y %h:%i%p') as date, 
  oi.items 
from orders 
inner join 
(
  select order_id,  group_concat(concat(cnt, ' x ', item_name)) as items 
  from
  (
    select order_id, item_name, count(*) as cnt
    from orders_items 
    group by order_id, item_name
  ) as counted
  group by order_id
) as oi on oi.order_id = orders.id;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, thats what I was looking for!
0

Further to the aforementioned query:

select    orders.*,    DATE_FORMAT(orders.created_at, '%d.%m.%Y
%h:%i%p') as date,    oi.items  from orders  inner join  (   select
order_id,  group_concat(concat(cnt, ' x ', item_name)) as items   
from   (
select order_id, item_name, count(*) as cnt
from orders_items 
group by order_id, item_name   ) as counted   group by order_id ) as oi on oi.order_id = orders.id;

I would add a

Having Count(*)>0

to eliminate any items with a 0 quantity

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.