MySQL: Find day with max orders - mysql

I have a very basic orders table:
+----------+---------+------------+---------+
| order_id | cust_id | order_date | book_id |
+----------+---------+------------+---------+
| 1 | 1 | 10/10/2014 | 1 |
+----------+---------+------------+---------+
| 2 | 1 | 10/10/2014 | 2 |
+----------+---------+------------+---------+
| 3 | 1 | 10/12/2014 | 1 |
+----------+---------+------------+---------+
| 4 | 2 | 10/18/2014 | 6 |
+----------+---------+------------+---------+
| 5 | 2 | 10/18/2014 | 77 |
+----------+---------+------------+---------+
| 6 | 2 | 10/18/2014 | 103 |
+----------+---------+------------+---------+
| 7 | 2 | 10/10/2014 | 13 |
+----------+---------+------------+---------+
| 8 | 3 | 10/09/2014 | 1 |
+----------+---------+------------+---------+
| 9 | 3 | 10/11/2014 | 2 |
+----------+---------+------------+---------+
| 10 | 3 | 10/12/2014 | 3 |
+----------+---------+------------+---------+
The query should:
- For each customer show order_date with Max number of orders. Example: customer 1 had 2 orders on 10/10/2014
- Special case: When customer has multiple days with most orders, show the earliest date. Example: customer 3 had 3 single item orders on different days. Need to show 10/09/2014.
I should be able to solve this without use of temp tables.
Kira

You need two clauses: 1) find the max number of orders per customer per day and 2) find the day on which the max number of orders occurred. The second step is needed to eliminate multiple days with same number of orders.
SELECT * FROM
(SELECT cust_id,
order_date,
count() cnt
FROM
orders
GROUP BY cust_id, order_date) x
JOIN
(SELECT cust_id,
MAX(cnt) max_cnt
FROM
(SELECT cust_id,
order_date,
count() AS cnt
FROM
orders
GROUP BY cust_id, order_date) n
GROUP BY cust_id) y
ON
y.max_cnt = x.cnt
AND
y.cust_id = x.cust_id
JOIN (SELECT x.cust_id,
min(x.order_date) AS dd
FROM
(SELECT cust_id,
order_date,
count() cnt
FROM orders
GROUP BY by cust_id, order_date) x
JOIN
(SELECT cust_id,
MAX(cnt) max_cnt
FROM
(SELECT cust_id,
order_date,
count() as cnt
FROM
orders
GROUP BY
cust_id, order_date) n
GROUP BY cust_id) y
ON
y.max_cnt = x.cnt
AND
y.cust_id = x.cust_id
GROUP BY cust_id) AS t2
ON
t2.cust_id=x.cust_id
AND
t2.dd=x.order_date;

Related

MySQL Total friends find multiple maximum if exist

I've a MySQL table where you have friends list.
+--------------+-------------+-------------+
| requester_id | accepter_id | accept_date |
+--------------+-------------+-------------+
| 1 | 2 | 2016-06-03 |
| 1 | 3 | 2016-06-08 |
| 2 | 3 | 2016-06-08 |
| 3 | 4 | 2016-06-09 |
| 1 | 5 | 2016-06-09 |
+--------------+-------------+-------------+
If there are multiple people with maximum number of friends (in this case 1 and 3 have 3 friends each), how can I print both 1 and 3 with their count.
I've the part where I can find the Nth largest person.
select s.requester_id, sum(s.total) as total_friends from (
select requester_id, count(accepter_id) as total from request_accepted
group by requester_id
union
select accepter_id, count(requester_id) as total from request_accepted
group by accepter_id
) as s
group by s.requester_id
order by total_friends desc;
I've managed to come up with this ugly but working code.
select s.requester_id, sum(s.total) as total_friends
from
(select requester_id, count(accepter_id) as total
from request_accepted
group by requester_id
union
select accepter_id, count(requester_id) as total
from request_accepted
group by accepter_id) as s
group by s.requester_id
having total_friends = (select max(s2.max_total)
from (select sum(s1.total) as max_total
from (select requester_id, count(accepter_id) as total
from request_accepted
group by requester_id
union
select accepter_id, count(requester_id) as total
from request_accepted
group by accepter_id) as s1
group by s1.requester_id) as s2)

How to calculate max values of groups?

I have a table like so (I'm not sure how to format tables)
Category / Products / Purchases
1 | A | 12
1 | B | 13
1 | C | 11
2 | A | 1
2 | B | 2
2 | C | 3
Expected output:
1 | B | 13
2 | C | 3
However I keep on getting
1 | A | 13
2 | A | 3
ie. It just selects the first occurrence of the second column.
Here is my code:
SELECT Category, Products, MAX(Purchases) FROM myTable GROUP BY Category;
Use filtering in the where clause:
select t.*
from t
where t.purchases = (select max(t2.purchases) from t t2 where t2.category = t.category);
With NOT EXISTS:
select m.* from myTable m
where not exists (
select 1 from myTable
where category = m.category and purchases > m.purchases
)
See the demo.
Results:
| Category | Products | Purchases |
| -------- | -------- | --------- |
| 1 | B | 13 |
| 2 | C | 3 |
You can use row_number() to identify max purchase for each group or replace rownumber() to rank() if there are ties of max purchases for each group
Select Category, Products,
Purchases from (Select Category,
Products,
Purchases,
row_number() over (partition by
category, products order by
purchases desc) rn from table) t
where t.rn=1
)

How to use Mysql SUM with JOIN

I have the following tables:
purchase_tbl
id | productId | purchaseQuantity
---+-----------+-----------------
1 | 1 | 30
2 | 2 | 30
3 | 1 | 10
4 | 2 | 10
sale_tbl
id | productId | saleQuantity
---+-----------+-------------
1 | 1 | 10
2 | 2 | 10
3 | 1 | 10
4 | 2 | 10
5 | 1 | 10
6 | 2 | 10
I need to get the output as this one:
productId | totalPurchasedQuantity| totalSaleQuantity
----------+-----------------------+------------------
1 | 40 | 30
2 | 40 | 30
I'm using this query and how to get the desired result?
SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM purchase_tbl
JOIN sale_tbl
ON purchase_tbl.productId = sale_tbl.productId
GROUP BY purchase_tbl.productId
Current output
productId | totalPurchaseQuantity | totalSaleQuantity
----------+-----------------------+------------------
1 | 120 | 60
2 | 120 | 60
You better group then in separate query, as table have multiple records for each product, which getting cross product.
SELECT purchase.productId, totalPurchaseQuantity, totalSaleQuantity
FROM
(SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
FROM purchase_tbl
GROUP BY purchase_tbl.productId) purchase
INNER JOIN
(SELECT sale_tbl.productId
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM sale_tbl
GROUP BY sale_tbl.productId
) sale ON sale.productId= purchase.productId;
To obtain your expected result you have to do the aggregation on the individual table before joining them. Your query with be like:
SELECT A.productId, A.totalpurchaseQuantity, B.totalsaleQuantity
FROM
(SELECT productId, SUM(purchaseQuantity)
totalpurchaseQuantity FROM purchase_tbl
GROUP BY productId) A JOIN
(SELECT productId, SUM(saleQuantity)
totalsaleQuantity FROM sale_tbl
GROUP BY productId) B ON
A.productId=B.productId;

Count the number of orders

I have a table (Table1) with the columns order_item_id customer_id and order_id in which I want to count the number of orders per customer. Unfortunately an order with more than one article has the same order_id
|order_item_id|order_id|customer_id|
| 2 | 30 | 1 |
| 3 | 30 | 1 |
| 4 | 42 | 1 |
| 5 | 33 | 2 |
| 11 | 32 | 3 |
| 12 | 33 | 2 |
| 13 | 33 | 2 |
| 19 | 69 | 3 |
Expected Outcome:
|numberOfOrders|customer_id|
| 2 | 1 |
| 1 | 2 |
| 2 | 3 |
I tried this (and many more):
CREATE TABLE X AS
SELECT
customer_id,
COUNT(order_id) AS `numberOfOrders`
FROM Table1 T1
GROUP BY customer_id;
The problem is, that with this solution it counts every article not the number of orders: so the number of orders for customer 1 is 3 (not 2), for customer 2 is 3 (not 1)....
How can I solve this for a big database with Mysql query?
Try the following solution to SELECT your data as expected:
SELECT COUNT(DISTINCT order_id) AS numberOfOrders, customer_id
FROM table1
GROUP BY customer_id
Demo: http://sqlfiddle.com/#!9/ee8f62/1/0
An option could be to do GROUP twice. First GROUP for the number of items per order, wrapped by a second GROUP for the number of orders per customer:
/* second group */
SELECT customer_id
, count(*) AS number_of_orders
FROM (
/* first group */
SELECT order_id
, customer_id
, count(*) AS order_item_count
FROM Table1
GROUP BY order_id, customer_id
) a
GROUP BY customer_id

Getting COUNT while ignoring GROUP BY

I have the following table: ProductSales
+-------+-----------+--------+-----------+
|prod_id|customer_id|order_id|supplier_id|
+-------+-----------+--------+-----------+
| 1 | 1 | 1 | 1 |
+-------+-----------+--------+-----------+
| 2 | 4 | 2 | 2 |
+-------+-----------+--------+-----------+
| 3 | 1 | 1 | 1 |
+-------+-----------+--------+-----------+
| 4 | NULL | NULL | Null |
+-------+-----------+--------+-----------+
| 5 | 1 | 1 | 2 |
+-------+-----------+--------+-----------+
| 6 | 4 | 7 | 1 |
+-------+-----------+--------+-----------+
| 7 | 1 | 1 | 3 |
+-------+-----------+--------+-----------+
I have a SELECT query:
SELECT customer_id AS customer, count(*) AS prod_count
, count(DISTINCT order_id) as orders
FROM ProductSales
WHERE supplier_id=1
GROUP BY customer_id
HAVING customer_id<>'NULL'
This will be produce the result:
+--------+----------+------+
|customer|prod_count|orders|
+--------+----------+------+
| 1 | 2 | 1 |
+--------+----------+------+
| 4 | 1 | 1 |
+--------+----------+------+
What I have been trying to achieve and getting nowhere is to add a fourth column in my results to show the number of order_ids that belong only to the current supplier for each customer:
+--------+----------+------+-------------+
|customer|prod_count|orders|Unique Orders|
+--------+----------+------+-------------+
| 1 | 2 | 1 | 0 | } Order '1' is connected with two supplier_ids
+--------+----------+------+-------------+
| 4 | 1 | 1 | 1 | } Order '2' is connected to only one supplier_id
+--------+----------+------+-------------+
(This gets more complex when there are more orders per customer associated with far more suppliers).
I thought I was close with:
SELECT t1.user_id, count(DISTINCT t1.prod_id) AS prod_count
, count(DISTINCT t1.order_id) as orders
, IF(count(DISTINCT t3.supplier_id)>1,0,1) AS Unique_Orders
FROM ProductSales AS t1
LEFT JOIN `order` AS t2 ON t1.order_id=t2.order_id
LEFT JOIN ProductSales AS t3 ON t2.order_id=t3.order_id
WHERE t1.supplier_id=1
GROUP BY t1.customer_id
HAVING t1.customer_id<>'NULL'
The orders table stated above is related to ProductSales only by order_id.
Which shows my Customers, Products(total), Orders(total) but the Unique Orders shows if there are unique orders (0) or not (1), I understand the logic of the IF statement and it does what I expect. It's working out how to find the number of unique orders which is baffling me.
The table is established and can't be changed.
Any suggestions?
Unique orders can be defined as
SELECT OrderID
FROM yourtable
GROUP BY OrderID
Having COUNT(Distinct SupplierID) = 1
So try
SELECT
customer_id AS customer,
count(*) AS prod_count.
count(DISTINCT productsales.order_id) as orders,
COUNT(distinct uqo)
FROM ProductSales
left join
(
SELECT Order_ID uqo
FROM Productsales
GROUP BY Order_ID
Having COUNT(Distinct supplier_id) = 1
) uniqueorders
on ProductSales.order_id = uniqueorders.uqo
WHERE supplier_id=1
GROUP BY customer_id