Counting column times number ordered in mysql - php

we are working with a table that has a column for every SKU ordered by a customer. So if a particular SKU has been ordered by five different customers, it will appear 5 times. Also, some customers may order 2 of that SKU so in the 'number_ordered' column next to it, there will be a 2. I'm not so good at drawing this out in words so I'll give an example of what the database looks like.
+------------+-----------------+
| item_SKU | Number Ordered |
+------------+-----------------+
| SKU001 | 3 |
| SKU001 | 2 |
| SKU002 | 15 |
| SKU003 | 1 |
+------------+-----------------+
How can I times the sku by the number ordered and then add them all together in MySQL. I need to put it into PHP but I can do that if i get some hints on how to do this.
Cheers

Use this to get the total ordered item of same item_SKU and use it in PHP. If you need the order count also, use COUNT() function
SELECT item_SKU, SUM(Number_Ordered) as Total_Ordered_Item, COUNT(Number_Ordered) as Total_Order_Count
FROM table
GROUP BY item_SKU

Try using count' with group by sku name (SKU001). it returns an output with the count of different sku's.

try below SQL query
1.Sum of Orders
select item_SKU,sum(number_ordered) as orders from `table Name` group by item_SKU order by item_SKU
output
item_SKU | Number Ordered
SKU001 | 5
SKU002 | 15
SKU003 | 1
2. Query to count no of orders
select item_SKU,count(number_ordered) as orders from `table Name` group by item_SKU order by item_SKU
output
item_SKU | Number Ordered
SKU001 | 2
SKU002 | 1
SKU003 | 1

Try this query:
SELECT item_SKU,
COUNT(item_SKU) CNT,SUM(Number_Ordered) TOTAL
FROM TABLE1 GROUP BY item_SKU;
SQL Fiddles

Select item_SKU, SUM(NumberOrdered) As total from [table name] group by item_SKU

Try this one. It gives you total no of occurrence as 'COUNT' and sum of number_ordered as 'SUM_NUM_ORDER'
SELECT item_SKU,COUNT(item_SKU) as COUNT,SUM(Number_Ordered) as SUM_NUM_ORDER FROM TABLE1 GROUP BY item_SKU;
DEMO: http://sqlfiddle.com/#!2/9ec2b9/10

Related

My current MySQL join is not working

I have the following tables:
Users
id | name
-----------------
1 | Johny Bravo
Orders
id | users_id | number
----------------------
1 | 1 | 111111
2 | 1 | 222222
3 | 1 | 333333
4 | 1 | 444444
Example
id | text | number
------------------
1 | test | 111111
2 | test | 111111
3 | test | 222222
4 | test | 222222
5 | test | 333333
6 | test | 333333
Desired Outcome
id: 1
name: Johny Brawo
count(orders): 4
count(example): 6
My current query, which doesn't work
SELECT users.id, users.name, count(orders.id), count(example.id)
FROM users
LEFT JOIN orders ON orders.users_id=users.id
LEFT JOIN example ON example.number=orders.number
GROUP BY users.id
My current result
id: 1
name: Johny Brawo
count(orders): 8
count(example): 8
Any help would be greatly appreciated.
try count(distinct orders.id), count(distinct example.id)
I've not done any MySQL really, but this works in other Databases...
Starting - a little bit of theory. What does your query do?
First it SELECTs something from users table.
Then it LEFT JOINs with orders table. Number of returned rows is a multiplication of rows from users table and matching rows from orders table. So with only this join you will have 6 rows, each one with Johny Bravo as user, but with different orders data.
Then - another LEFT JOIN. This time with example table. Again - a number of returned rows is a multiplication of rows from orders table and matching rows from example table. So without GROUP BY and COUNT you will have eight rows of result.
Now, the GROUP BY query part. What does it do? It just groups rows with matching GROUP BY column(s). So it will group all rows with same users.id. There are eight of them.
Standard COUNT() will return a number of rows with not null value. As there were eight rows, both counts will return 8.
Now, as #GPW suggested, the solution is a COUNT(DISTINCT x). This function returns a count of unique not null rows.
Thus, the query should look like:
SELECT users.id, users.name, count(DISTINCT orders.id), count(DISTINCT example.id)
FROM users
LEFT JOIN orders ON orders.users_id=users.id
LEFT JOIN example ON example.number=orders.number
GROUP BY users.id
UPDATE - ordering and strict databases
You have also asked about ordering the result. You can order it by any column from your query. As MySQL is not very strict when it comes to grouping, you will also be able to order by any column from users table, as users table results are unique (grouped by id). You can also add, for example ORDER BY COUNT(DISTINCT orders.id) DESC to find users with largest number of orders.
Most databases, though, is more strict in GROUP BY queries. It allows to SELECT only columns with aggregated values or those explicitly contained in GROUP BY clause. So your GROUP BY clause should rather look like
GROUP BY users.id, users.name

MySQL - I need to SELECT the highest umber in a column when there are multiple ID's

Take the following dataset:
id | Number
1 | 6534
1 | 765
1 | 1234
2 | 744
2 | 6109
3 | 333
3 | 9888
3 | 3112
3 | 98432
I want to show the highest Number for each id.
So Like this:
id | Number
1 | 6534
2 | 6109
3 | 98432
How can I do this with a SELECT statement?
I've already tried the following:
SELECT * FROM mytable ORDER BY id, Number Desc
But this shows the entire dataset.
I'm not trying to get the number of occurences. I am trying to get the highest Number grouped by id but can't get it to work.
SELECT id, MAX(Number) as Number FROM mytable GROUP BY id
You can try :
Select id,max(Number) from Your_Table group by id
Your Query that you have tried, it will only order your Data table by the given parameters.
In the meantime, What i have proposed to you, will select the two columns you want to diplay (the id, and the maximum of the column "Number").
And the group by will help to the maximum of each group. That's why a group by id is the right clause to have the maximum of each group of Ids.
Most of time the id field is incremental but for your case you can use.
SELECT MAX(number) FROM `user` GROUP BY id
Where number is the column name from which you want to find MAX, and user is your table name.

LIMIT result on join MySQL

take the case you have 2 table, for example tbCostumers and tbOrders.
I would like to display a summary list with all costumers, related orders and display them with a paginator.
Doing a join I can extract costumers list and all orders for each costumer, the result is something like:
idCostumer | name | ... | idProduct | productName | price | ...
Where the first n columns are all equal if the costumer has more than 1 order. So I can have:
1 | will | ... | 12 | product1 | 123 | ...
2 | bill | ... | 23 | product2 | 321 | ...
2 | bill | ... | 24 | product3 | 231 | ...
And so on
I'm trying to use LIMIT to extract only n records and using them with a paginator.
First question: if a costumer has more than 1 order, with this query I'll see n records, equal in the first column (id, name, ... and other costumer info) but different at the end, where there are products info. Is this 'correct'? Is there another way to extract this informations?
Second question: if I do that and I use a LIMIT, I could "cut" the result table between 2 (or more) records that represent the same customer; so, for example in the small table above, if I limit with 2 the third row will be lost, even if it's part of the row above, because is just another order of the same costumer.
I would like to limit the number of different idCostumer, in order to take exactly n costumers, even if they appear more than 1 times in the result table. Something like n different idCostumer, no matter if they are repeated.
Is this possible?
I hope it's clear, it was not easy to explain what I would like to achieve :)
Thank you!
You might want to have something like this:
SELECT * FROM (
(SELECT * FROM tbCustomers LIMIT 3) AS c
INNER JOIN tbOrders AS o ON o.customer = c.idcustomer
);
You can substitute the first asterisk with named columns and only receive your desired columns in the order you prefer (ie: SELECT c.name, o.price FROM...) .
Hope this works for you!
EDIT: changing the value of the LIMIT clause changes the number of the picked customers, of course.
EDIT 2: As Alvaro Pointed out, you'll probably need an order clause in the tbCustomers query.

MySQL - Selecting the sum amount based on specific condition

I've searched for a few hours now, but couldn't find relative solution to a specific algorithm I am working on. To simplify the obstacle, I would like to present the information in just one table.
_____________________________________
| User | Item | price | qty |
-------------------------------------
| Annie | Dress | 80 | 1 |
| Bob | Jeans | 65 | 3 |
| Cathy | Shoes | 60 | 4 |
| David | Shirts | 40 | 6 |
| Annie | Shoes | 60 | 2 |
| Bob | Shirts | 55 | 2 |
| Cathy | Jeans | 65 | 1 |
| David | Ties | 20 | 5 |
-------------------------------------
Problem # 1: Show users whose total price for shopping at the store is 300 or more and quantity of their purchase is less than or equal to 3. These shoppers will be mailed a coupon for $40.
Problem # 2: Show users whose total qty is greater than or equal to 7 and the total for price is 275 or more. These shoppers will be mailed a coupon for $20.
The rows within the table are not transaction specific. The table can represent separate transactions within a month. We're just trying to find certain returning customers who we would like to reward for shopping with us.
I'm not sure if this can be done only via MySQL, or if I need to have separate queries and store rows into arrays and compare them one by one.
What I have tried so far are the followings:
SELECT * FROM table where SUM(price) as Total >= 300 AND SUM(qty) <=3;
I've also tried the following after the research:
SELECT SUM(price) as Total FROM table WHERE SUM(qty) <=3;
I keep getting syntax errors in MySQL shell. You don't have to solve the problems for me, but if you can guide me through the logic on how to solve the problems, I'd appreciate it very much.
Lastly I'd like to ask once, can I solve this with only MySQL or do I need to store the rows into PHP arrays and compare each indexes?
You can't use an aggregate function in the WHERE clause, you have to use HAVING. WHERE operates on individual rows during the selection, HAVING operates on the final results after aggregating.
SELECT *, SUM(price*qty) as Total
FROM table
GROUP BY user
HAVING Total >= 300 AND SUM(qty) <= 3
SUM is an aggregate function, meaning it applies to a group of clubbed rows. S say i am grouping the table data based on NAME then sum function would sum all the price of one NAME.
Having said this, if you think logically it would not make any sense to put the sum(price) in a WHERE clause because where clause would not know which SUM(PRICE) for which NAME to operate on(where clause operates only after a temporary view has been generated).
So we have the HAVING clause in SQL. This is used to compare the results of aggregrate function at each step of aggregation.
Consider it like this:
In where clause, when the ANNIE row from your DB is returned, it does not know what SUM(PRICE) means.
While in HAVING clause the SUM(PRICE)>300 condition is executed only when SQL has finished grouping all the ANNIE data into one group and calculated the SUM(PRICE) for her.
For question 1:
SELECT USER, SUM(PRICE)
FROM table
GROUP BY user
HAVING SUM(PRICE) >= 300 AND SUM(QTY) <= 3
For Question 2:
SELECT USER, SUM(PRICE)
FROM table
GROUP BY user
HAVING SUM(PRICE) >= 275AND SUM(QTY) >=7

MYSQL query to sum multiple columns in different tables

I have two tables (orders, order_lines) with a one to many relationship. The orders table will have one row and the order_lines table will have one row for each product attached to the order.
ORDERS
+----------+-------------+---------------+
|order_num | total_order | shipping_total|
+----------+-------------+---------------+
| 12345 | 75.00 | 15.00 |
+----------+-------------+---------------+
ORDER_LINES
+----------+-------------+-------+
| order_num| volume | price |
+----------+-------------+-------+
| 12345 |10 |25.00 |
+----------+-------------+-------+
| 12345 |20 |25.00 |
+----------+-------------+-------+
| 12345 |20 |25.00 |
+----------+-------------+-------+
I would like to sum the total_order & shipping_total columns in the ORDERS table and the volume & price columns in the ORDER_LINES table.
Query currently not working:
SELECT b_orders.bill_country, b_orders.ship_country
, SUM(volume) AS v, SUM(price) AS pt
, SUM(shipping_total) AS st, SUM(total_order) AS tot_o
FROM b_orders
JOIN b_order_lines
ON b_orders.order_num = b_order_lines.order_num
WHERE DATE(b_orders.order_date) BETWEEN '2012-04-02' AND '2012-04-06'
AND ship_country = 'USA'
AND b_order_lines.price > 0;
This query is returning the wrong values. I kind of know why but have no idea how to write the proper query...please help.
When you use an aggregate function line SUM, you need to tell the SQL server what columns are going to be used to GROUP BY for doing the sums.
So if you add the following to the bottom of your query:
GROUP BY
b_orders.bill_country, b_orders.ship_country
This will tell it to give you the sum for each unique combination of bill_country, ship_country in the data. Is this what you are looking for?
If bill_country and ship_country are going to be included in a query that also has aggregate functions like SUM, you need to group on them. I suspect all you need is to add this line at the end:
GROUP BY b_orders.bill_country, b_orders.ship_country;
If you don't need to see them, you can remove them from the SELECT statement and omit the grouping; you don't have to select columns to include them in the WHERE clause.

Categories