I need to display the Lastname when the total number of ordered products in 1 order is greather than 2 and I need to calculate the avg of commanded products. The output must be :
| LASTNAME | AVG |
--------------------
| SMITH | 2.5 |
| HARRIS| 2.75 |
------------------
I'm trying this
SELECT c.customer_id,firstname,lastname,count(o.order_id)*1.0/(select distinct count(*)FROM ORDERS where order_id=o.order_id)
FROM customer c,PURCHASES p,ORDERS o
WHERE c.customer_id=p.customer_id and p.order_id=o.order_id
and o.order_id in (SELECT order_id
FROM ORDERS
GROUP BY order_id
HAVING COUNT(*) > 2)
group by c.customer_id
It seems to be correct, but I get incorrect answer.
Here is the table of relation between CUSTOMER and ORDERS
| LASTNAME | ORDER_ID | PRODUCT_ID |
------------------------------------
| SMITH | 0 | 91 |
| SMITH | 0 | 122 |
| WILLIAMS | 1 | 179 |
| SMITH | 2 | 50 |
| SMITH | 2 | 43 |
| SMITH | 2 | 200 |
| HARRIS | 3 | 105 |
| HARRIS | 3 | 173 |
| HARRIS | 4 | 29 |
| HARRIS | 4 | 158 |
| JACKSON | 5 | 75 |
| WILLIAMS | 6 | 55 |
| HARRIS | 7 | 86 |
| HARRIS | 7 | 143 |
| HARRIS | 7 | 152 |
| HARRIS | 7 | 197 |
| HARRIS | 7 | 198 |
| BROWN | 8 | 149 |
| HARRIS | 9 | 117 |
| HARRIS | 9 | 177 |
| WILLIAMS | 10 | 116 |
| JACKSON | 11 | 13 |
| JACKSON | 11 | 188 |
| WILLIAMS | 12 | 17 |
| WILLIAMS | 12 | 89 |
------------------------------------
CodePudding user response:
SELECT LASTNAME, Products/Orders
FROM (
SELECT
LASTNAME,
COUNT(DISTINCT ORDER_ID) Orders,
COUNT(PRODUCT_ID) Products
FROM Table1
GROUP BY LASTNAME
)x
WHERE LASTNAME IN (
SELECT LASTNAME
FROM (
SELECT
LASTNAME,
COUNT(PRODUCT_ID) OVER (PARTITION BY LASTNAME,ORDER_ID) c
FROM Table1
)x
WHERE c>=3
)
result:
| LASTNAME | Average |
|---|---|
| HARRIS | 2.7500 |
| SMITH | 2.5000 |
CodePudding user response:
This will work for MySQL >= 8
# gets all usernames which have have at least one order with more than two items
with users(name) as (
select distinct name
from orders
group by name, orderid
having count(productid) > 2
),
# gets the size of each order for the names
ordersize(name, productcount) as (
select u.name, count(productid)
from users u inner join orders o on u.name = o.name
group by u.name, orderid
)
# get the average of productcount
select name, avg(productcount)
from ordersize
group by name
See also this Fiddle
CodePudding user response:
Example here for MySQL > 8.0. DDL is in the linked Fiddle - I've gone off Customer_ID instead of Lastname, because the latter wouldn't really work in real life.
-- First CTE - Get the customers with two or more orders
WITH cte1 AS
(
SELECT
Customer_ID,
COUNT(DISTINCT Order_ID) AS OrderCount
FROM
CustomerOrder
GROUP BY
Customer_ID
HAVING
COUNT(DISTINCT Order_ID) >= 2
), cte2 AS
-- Get product counts per order
(
SELECT
co.Customer_ID,
co.Order_ID,
COUNT(DISTINCT Product_ID) AS Products
FROM
CustomerOrder co
INNER JOIN
cte1
ON cte1.Customer_ID = co.Customer_ID
GROUP BY
co.Customer_ID,
co.Order_ID
)
-- Finally, average products per order
SELECT Customer_ID, AVG(Products) AS AverageProductsInOrder
FROM cte2
GROUP BY
Customer_ID;
https://www.db-fiddle.com/f/dKkSN5H9DioyouAppAErn1/0
CodePudding user response:
declare @tmp as table(LASTNAME varchar(20),ORDER_ID int, PRODUCT_ID int)
insert into @tmp values('SMITH', 0 , 91 )
,('SMITH', 0 , 122 )
,('WILLIAMS', 1 , 179 )
,('SMITH', 2 , 50 )
,('SMITH', 2 , 43 )
,('SMITH', 2 , 200 )
,('HARRIS', 3 , 105 )
,('HARRIS', 3 , 173 )
,('HARRIS', 4 , 29 )
,('HARRIS', 4 , 158 )
,('JACKSON', 5 , 75 )
,('WILLIAMS', 6 , 55 )
,('HARRIS', 7 , 86 )
,('HARRIS', 7 , 143 )
,('HARRIS', 7 , 152 )
,('HARRIS', 7 , 197 )
,('HARRIS', 7 , 198 )
,('BROWN', 8 , 149 )
,('HARRIS', 9 , 117 )
,('HARRIS', 9 , 177 )
,('WILLIAMS', 10 , 116 )
,('JACKSON', 11 , 13 )
,('JACKSON', 11 , 188 )
,('WILLIAMS', 12 , 17 )
,('WILLIAMS', 12 , 89 )
select LASTNAME,
sum(numerator),
count(*),
sum(numerator)/cast(count(*) as decimal(18,3)) avg
FROM
(
select
LASTNAME,ORDER_ID, COUNT(*) numerator
from @tmp tmp
where tmp.LASTNAME
IN
(
select LASTNAME from @tmp tmp2
group by LASTNAME
having count(*)>2
)
GROUP BY LASTNAME,ORDER_ID
)x
GROUP BY LASTNAME
having sum(numerator)/cast(count(*) as decimal(18,3))>2
ORDER BY LASTNAME
output:
LASTNAME (No column name) (No column name) avg
HARRIS 11 4 2.7500000000000000000
SMITH 5 2 2.5000000000000000000
