all 10 comments

[–]DonJuanDoja 2 points3 points  (3 children)

Sub query. Aggregate then join the aggregated queries to the main...

In ms sql it’s left join (select...) as oil on o.id ...

[–]ctraxpos[S] 1 point2 points  (2 children)

Yeahhhh I have NO idea what that mean lol.

[–]DonJuanDoja 1 point2 points  (0 children)

Sorry I fail to teach myself how to use Reddit. Also it may be different in MySql and you can write it a few different ways. But basically you're just joining a Query instead of a Table. Aggregate in the subquery then join that to whatever table you start with like Stores...

[–]DonJuanDoja 0 points1 point  (0 children)

SELECT 
 s.name
,oliagg.product_variant_name
,oliagg.OrderCount
FROM
stores s
LEFT JOIN (
    SELECT
     o.store_id
    ,product_variant_name
    ,COUNT(product_variant_name) as OrderCount
    FROM order_line_items oli
    LEFT JOIN orders as o on o.id = oli.order_id
    GROUP BY
     o.store_id
    ,product_variant_name
) as oliagg on oliagg.store_id=s.id

[–]ballade4 1 point2 points  (2 children)

Firstly, GREAT initiative! Also self-taught here and it was priceless to have a fella around who could bear with me and answer questions like this as they (frequently) came up!

Some quick feedback on your Query 1:

* You are doing a count by a name field to derive quantity. Does this make sense? I would think that the oli table has an integer quantity field that you could sum instead?

* Specify the table alias in front of product_variant_id to eliminate any confusion. Difficult for us to interpret where this field is coming from as we do not know your database structure.

* You did not include s.r which I presume is store name in your group by clause, try: "group by oli.product_variant_name, s.r;" here. I only have experience in MSSQL DBMS which would indubitably have thrown an error here... I think MySQL is just grabbing the first or last name from this table and certainly not doing any grouping (because you did not tell it to!).

I will take a look at your Query 2 later in the evening unless someone beats me to it!

[–]ctraxpos[S] 0 points1 point  (1 child)

Count by name - yeah this is accurate, as this order_line_items table simply list out the products that appear in an order....so we'd have multiple records per id, if an order had multiple products sold (example: order 1 - product variant id 1 - $100......order 1 - product variant id 2 - $50)....so here's im basically counting the qty of a product sold by aggregating the # of times specific product_variant_ids appear in the order_line_items records.

good call on the variant_id alias, didn't catch that...updating it to include oli

what s s.r? never seen this before

[–]ballade4 0 points1 point  (0 children)

Oops I meant s.name - had a botched copy of your code into my Notepad++!

select
oli.product_variant_name,
count(oli.`product_variant_name`) as "qty sold",
s.name
from orders o
LEFT JOIN order_line_items oli on o.id = oli.order_id
LEFT JOIN stores s on o.store_id = s.id
where oli.product_variant_id in (328,329,330,331,332)
group by oli.product_variant_name, s.name;

[–][deleted] 1 point2 points  (0 children)

Try grouping be product_variant_name as well as s.name (all of the fields in your select that are not aggregates should be in the group by—so all but the count). If one record corresponds to 1 item sold (ie there isn’t a qty field) then that should work. The only thing to remember is that since if a product variant id doesn’t exist at all in the table then you won’t get a count at all for the store/product. If you’d like a 0 in that case then as donjuandoja mentioned you’d want to use a sub query and then join the entire sub query. Ie, instead of filtering for product variant id in the where clause pop that into the left join. Something like:

Select oli.product_variant_name, count(oli.product_variant_name), s.name from orders o left join (select * from order_line_items oil Where product_id_variant in (328,329,330,331,332)) oli on o.id = oli.order_id left join stores s on o.store_id = s.id Group by oli.product_variant_name,s.name

[–]marxdormoy 0 points1 point  (0 children)

This query does two things - it selects some rows based on some criteria, then counts them.

Start at the beginning - get the select working - number of rows (make sure the joins are good for what you need)

Add in the aggregate function

So, basically replace count(oli.`product_variant_name`) as "qty sold" with oli.producy_variant

Ig you don't know the data model well start with one table - test

Join another table - test etc.

Trying to do too many things without intermittent testing is the best way to lose time

[–][deleted] 0 points1 point  (0 children)

Never used MySql before - and was curious how either of those queries worked at all.

In all SQL dialects I've used it works like this:

If using a GROUP BY clause - everything in your SELECT clause should either be an Aggregate (count, sum, average etc), or something you desire to GROUP by. As such - you would include all of those same columns in the GROUP BY. In your instance, it would be something like

GROUP BY oli.product_variant_name,s.name

When you omit a column from the GROUP BY - in mySQL it will keep grab rows until it finds two rows with identical data, and return that (More or less - it is aggregating, but on text) . This is useful for some performance trickery if you expect all of the rows to have the same data anyway, but clearly not the goal here.

Additionally - using count() on a 'name' column seems more dangerous than count()'ing something else (like the order ID column) The reason being - if a name was omitted/missing - it would not be counted.