-1

I'm struggling to try to have the count of order id on an item_id row, any help is greatly appreciated!

Data
item_id | order_id
1 | Order_1
2 | Order_1
3 | Order_2
4 | Order_3
Desired Result

item_id | order_id | items_in_order
1 | Order_1 | 2
2 | Order_1 | 2
3 | Order_2 | 1
4 | Order_3 | 1


   SELECT S.item_id, S.`order_id`, S.order_total, C.cnt as items_in_order,

       `order_discount` / C.cnt as item_discount,
                `order_total` / C.cnt  as item_price
FROM `orders` S 
LEFT JOIN (SELECT `item_id`, `order_id`, count(`order_id`) as cnt  FROM `supplier_orders` GROUP BY `order_id`) 
C ON S.`order_id` = C.`order_id` AND S.id = C.item_id

This would produce this with null values
item_id | order_id | items_in_order | item_discount | item_price
3009117 | 3029511 | 2    | 0    | 25 
3009118 | 3029511 | null | null | null 

UPDATE, this now seems to work as intended

SELECT S.`item_id`, S.`order_id`, S.order_total, C.cnt as items_in_order,

       `order_discount` / C.cnt as item_discount,
                `order_total` / C.cnt  as item_price
FROM `orders` S 
INNER JOIN (SELECT `item_id`, `order_id`, count(`order_id`) as cnt  FROM `orders` GROUP BY `order_id`) 
C ON S.`order_id` = C.`order_id` 
GROUP BY S.`item_id`

  • Why you have Order prefix in Order_id column. – Ankit Bajpai Jun 13 '20 at 00:30
  • Thanks for spotting, the output should include order_id – Simon Crowther Jun 13 '20 at 00:45
  • Please in code questions give a [mre]--cut & paste & runnable code, including smallest representative example input as code; desired & actual output (including verbatim error messages); tags & versions; clear specification & explanation. Give the least code you can that is code that you show is OK extended by code that you show is not OK. (Debugging fundamental.) For SQL that includes DBMS & DDL (including constraints & indexes) & input as code formatted as a table. [ask] Pause work on the overall goal, chop code to the 1st expression not giving what you expect & say what you expect & why. – philipxy Jun 13 '20 at 01:43
  • What does 'id' represent in the desired result? – Strawberry Jun 13 '20 at 07:14
  • @Strawberry An unclear comment on the answer might be trying to say that it should be item_id. Why don't you help & downvote & close vote until a [mre] turns up? – philipxy Jun 13 '20 at 07:30
  • Please format that code reasonably & take the normal text out of the table. And we still can't cut & paste & run. And you haven't found the first subexpression that you consider wrong & said why. Then googled SO for a clear phrasing of the problem. You also don't clearly explain what you want your query to return. Etc. – philipxy Jun 15 '20 at 12:59
  • If you have an answer, please post it as an answer including explanation, don't add it to your question. You can accept it after minimum wait. But please edit your question to be a good one. – philipxy Jun 15 '20 at 13:07

1 Answers1

0

Your query does not relate to your sample data; however you seem to want aggregation and ranking. In MySQL 8.0, you would do:

select
    row_number() over(order by count(*) desc) rn,
    order_id,
    count(*) items_in_order
from data
group by order_id
order by rn

I named the first column rn (for rank): I find id confusing here, since you already have a column with that name in the table.

In earlier versions, one option uses a session variable instead of row_number():

select @rn := @rn + 1 rn, order_id, items_in_order
from (
    select order_id, count(*) items_in_order
    from data
    group by order_id
    order by items_in_order desc
) t
cross join (select @rn := 0) r
order by items_in_order desc
GMB
  • 216,147
  • 25
  • 84
  • 135
  • Thanks for sharing, sorry I threw off with id, that more understandably would be item_id, as this is unique, I have a limitation in that over is not compatible – Simon Crowther Jun 13 '20 at 01:32
  • @SimonCrowther: you are probably running a 5.x version of MySQL. You can use the second query, as explained in my answer. – GMB Jun 13 '20 at 01:33
  • @SimonCrowther & GMB Reading & writing the same variable in the same SELECT statement is deprecated in 8 and never had a defined/guaranteed behaviour. Someone from Percona said they found a safe way to do it within a CASE for certain versions by exploring the implemenation, but I don't have a link. – philipxy Jun 13 '20 at 07:27
  • @philipxy: I understand what you are refering to. This is not the case here, since all we do is increment the variable, we are not reading it in some other column - so this is safe. And, in versions 5.x, where window functions are available, this is a valid and efficient way to go... – GMB Jun 13 '20 at 08:26
  • It appears on both sides of an assignment. That is reading & writing. It is documented to not be defined in the manual (re variables & re assignment) & in a defect/bug report. But I don't expect to convince people that their beliefs & arguments based on guesses & hypotheses are unjustified. (No offence intended.) – philipxy Jun 13 '20 at 08:28
  • @philipxy: no offence for sure! Just technical discussion here. The [manual says](https://dev.mysql.com/doc/refman/8.0/en/user-variables.html): *The order of evaluation for expressions involving user variables is undefined. For example, there is no guarantee that `SELECT @a, @a:=@a+1` evaluates `@a` first and then performs the assignment.* You can see this clearly refers to assigning a variable *and* reusing it in another column. A self -incrementing increment is just fine. – GMB Jun 14 '20 at 17:55
  • That is not all that the 3 places I mentioned say. (In case it matters, I didn't say that the expression is disallowed, I said that the behaviour is not defined.) See my comments [here](https://stackoverflow.com/q/1895110/3404097) or at other hits googling 'site:stackoverflow.com mysql "philipxy" variable (write OR assign OR set) select' with or without 'percona'. We disagree. Again with no offence meant: People have personal (folk/naive) semantics & execution models not justified by or consistent with documentation. People will misinterpret anything to make it consistent with their beliefs. – philipxy Jun 15 '20 at 00:08
  • Thanks guys, I'm sorry for the badly formatted question, but I'm assuming this is not possible. Appreciate the help, I've changed id to item_id to show this is unique to the order id. Is there another approach to this problem? Below was another attempt. My ultimate goal is for each item_id row, show the total count of item_ids that have the same order_id, but keep the data not grouped by order_id but item_id – Simon Crowther Jun 15 '20 at 12:14
  • @SimonCrowther Please clarify via edits, not comments. You haven't yet posted a [mre] so there is no reason to worry about an answer to your (as yet not clearly posted) question. PS The right way to do something like the second code block here is to involve an SQL procedure. – philipxy Jun 15 '20 at 13:13