practitioner
asked on
MySQL query, not able to get correct result with Where, Group by and having
Hi,
A table stores order status at various stages,
Pending (1), when the order is placed,
Processing (2), when the packaging and shipping starts,
Delivered (3), when it reaches the customer.
etc.
Following shows with sample data how it is stored, first 3 records say that order #200 is Delivered on 17th March, Processing on 16th March, Pending on 15th March:
I want to list all the orders where there is only one status which is Pending (1), this order should not have other status e.g. Processing (2) or Delivered (3)
So I wrote this query but I'm not sure how correct it is:
SELECT `orders_id`
FROM `orders_status_history`
GROUP BY `orders_id`
HAVING COUNT(`orders_status_id`) = 1
ORDER BY `orders_id`
Regards
A table stores order status at various stages,
Pending (1), when the order is placed,
Processing (2), when the packaging and shipping starts,
Delivered (3), when it reaches the customer.
etc.
Following shows with sample data how it is stored, first 3 records say that order #200 is Delivered on 17th March, Processing on 16th March, Pending on 15th March:
orders_status_history_id, orders_id, orders_status_id, date_added
409, 200, 3, 2010-03-17
408, 200, 2, 2010-03-16
407, 200, 1, 2010-03-15
405, 196, 2, 2010-03-15
404, 196, 1, 2010-03-14
...
...
...
7, 2, 3, 2009-08-04
I want to list all the orders where there is only one status which is Pending (1), this order should not have other status e.g. Processing (2) or Delivered (3)
So I wrote this query but I'm not sure how correct it is:
SELECT `orders_id`
FROM `orders_status_history`
GROUP BY `orders_id`
HAVING COUNT(`orders_status_id`) = 1
ORDER BY `orders_id`
Regards
Question: Why would you have more than one record for the same order? Surely if your orders are going throug the process you are only going to have one record for each order.
Your sample data does not show duplicates but your post and query seem to indicate that they are.
Assuming there are then this will do what you want
Your sample data does not show duplicates but your post and query seem to indicate that they are.
Assuming there are then this will do what you want
SELECT `orders_id`
FROM `orders_status_history`
WHERE status = 1
GROUP BY `orders_id`
HAVING COUNT(`orders_status_id`) = 1
ORDER BY `orders_id`
Hi ,
What is the problem with your sql ? For me it looks correct .
Thx
What is the problem with your sql ? For me it looks correct .
Thx
ASKER
Hi everyone,
Thanks for the responses.
@Magento,
I wanted to confirm if I've written it correctly so that I'm getting the correct result.
@ Sharath_123,
It gives me different result from my query, I'm more confused, which one is correct?
@julianH,
It's not correct since WHERE clause in your query makes the Grouping ineffective.
Regards
Thanks for the responses.
@Magento,
I wanted to confirm if I've written it correctly so that I'm getting the correct result.
@ Sharath_123,
It gives me different result from my query, I'm more confused, which one is correct?
@julianH,
It's not correct since WHERE clause in your query makes the Grouping ineffective.
Regards
I want to list all the orders where there is only one status which is Pending (1)Can't see how you can get away without a filter - the where clause is necesary.
Your query is not going to work because nowhere does it actually check the value of the status and you specifically only want status=1 if I read your question correctly
What I don't understand is why you are using group and count?
If all you want is all orders that have a status of 1 - unless you are creating duplicate records with a status of 1 then there is no need to do the group - and even if there are duplicates you are saying you are only interested in records that have only 1 status pending - which does not make sense.
Why does this not give you what you want
SELECT `orders_id`
FROM `orders_status_history`
WHERE orders_status_id=1
ORDER BY `orders_id`
If this is not correct then please say from your sample data what you expect the results to look like.
Ok I understand what you want now - you want only those orders that have a single status record and it must be pending ...
Here is what you want
SELECT orders_status_history_id, orders_id
FROM orders_status_history
WHERE orders_status_id = 1 AND orders_id IN
(
SELECT orders_id FROM orders_status_history GROUP BY orders_id HAVING COUNT(*) = 1
)
The subquery will return all orders that have only one record - the outer query will filter those to be only those with a status of 1.
@ Sharath_123,
It gives me different result from my query, I'm more confused, which one is correct?
The query I posted should give exactly what you are looking for. Verify the result of that query if it is matching with your expected result. If you have problem, post here, will look into that.
It gives me different result from my query, I'm more confused, which one is correct?
The query I posted should give exactly what you are looking for. Verify the result of that query if it is matching with your expected result. If you have problem, post here, will look into that.
@Sharath_123 - question - how is your query going to ensure only records with status 1 are returned - you have no filter for orders_status_id other than a min and max which only checks for instances not values?
@practitioner - please try the query I posted above and let me know if that works. I have tested against a mockup of your database and it appears to work as expected.
@practitioner - please try the query I posted above and let me know if that works. I have tested against a mockup of your database and it appears to work as expected.
ASKER
Alright guys,
I'm back, will check it today and get back.
Thanks
I'm back, will check it today and get back.
Thanks
julianH - If you have time, you can test and let me know if it is not working. Thanks.
ASKER
@julianH, it did not return any result as this always gets stuck, I guess I need to run it on a test database with less number of records.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Julian,
I really appreciate your kind support. I wanted to list all these orders to make sure that I'm updating the correct ones. So instead of using a query and update them in one shot, I wrote a small PHP code, added it to the CRON so that it can update a few records every time the cron runs, the cron runs every 5th minute and it took almost 24 hours to fix this problem on my database.
Now, how do i assign the points and accept the solution so that if someone with similar requirement comes on EE knows that this is the answer :-)
Regards
I really appreciate your kind support. I wanted to list all these orders to make sure that I'm updating the correct ones. So instead of using a query and update them in one shot, I wrote a small PHP code, added it to the CRON so that it can update a few records every time the cron runs, the cron runs every 5th minute and it took almost 24 hours to fix this problem on my database.
Now, how do i assign the points and accept the solution so that if someone with similar requirement comes on EE knows that this is the answer :-)
Regards
Which answer do you want to accept?
Your original question was
The answer to your question is what I wrote in my last post - what you had is correct.
Your original question was
So I wrote this query but I'm not sure how correct it is:
The answer to your question is what I wrote in my last post - what you had is correct.
ASKER
Hi Moderator,
How do I accept my own post as the best solution and award points to the experts who helped me?
How do I accept my own post as the best solution and award points to the experts who helped me?
@practitioner close the question as you normally would - accept your own answer with 0 points and assign points to other questions as per normal.
ASKER
Alright, so the answer is my own query as approved by Julian:
SELECT `orders_id`
FROM `orders_status_history`
GROUP BY `orders_id`
HAVING COUNT(`orders_status_id`) = 1
ORDER BY `orders_id`
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I think the answer's intention was to accept own answer 0 points and this answer as assisted a39451928
ASKER
You are absolutely right Julian, I messed up in hurry, thanks for raising the objection.
NP :)
ASKER
Thanks Moderator.
@Julian, although I fixed my issue by writing a small PHP code and looped through to save time, I checked once again my original query and figured out the the part which is missing in it and why I was not sure at the time of posting this, yes, the missing part in my query is filtering the results further by checking if the orders_status_id value is 1 which is pending and not any other, the other values are from 2 to 8 that denotes different status of an order e.g. shipped, processed etc.
In fact, you tried to filter this in
Your suggestion and I tried it today again with no luck, so we are again in the discussion mode and can't close it as it will be misleading solution :-)
I apologize for the inconvenience but glad that it was not closed with wrong solution.
@Julian, although I fixed my issue by writing a small PHP code and looped through to save time, I checked once again my original query and figured out the the part which is missing in it and why I was not sure at the time of posting this, yes, the missing part in my query is filtering the results further by checking if the orders_status_id value is 1 which is pending and not any other, the other values are from 2 to 8 that denotes different status of an order e.g. shipped, processed etc.
In fact, you tried to filter this in
Your suggestion and I tried it today again with no luck, so we are again in the discussion mode and can't close it as it will be misleading solution :-)
I apologize for the inconvenience but glad that it was not closed with wrong solution.
Try this one
SELECT orders_status_history_id, orders_id
FROM orders_status_history
WHERE orders_status_id = 1 AND orders_id IN
(
SELECT orders_id FROM orders_status_history GROUP BY orders_id HAVING COUNT(*) = 1
)
Any update on my last post?
ASKER
Hey Julian,
Sorry dear, I could not check it.
I tried it today and the MySQL server stopped responding, PHPMyAdmin says "lost connection to MySQL"
@SouthMod, I understand that a timely response is expected from the one who posted the question, I'll respond on time.
Sorry dear, I could not check it.
I tried it today and the MySQL server stopped responding, PHPMyAdmin says "lost connection to MySQL"
@SouthMod, I understand that a timely response is expected from the one who posted the question, I'll respond on time.
Open in new window