sql grouping finding average - mysql

i am looking to find the avg cost for the total cost of each order but my grouping function is invalid
SELECT AVG(SUM(quantityOrdered*priceEach)) AS total
FROM orderdetails od
GROUP BY orderNumber
below is a snippet of my database
orderNumber productCode quantityOrdered priceEach orderLineNumber
10100 S24_3969 49 35.29 1
10101 S18_2325 25 108.06 4
10101 S18_2795 26 167.06 1
10101 S24_1937 45 32.53 3
10101 S24_2022 46 44.35 2
10102 S18_1342 39 95.55 2
10102 S18_1367 41 43.13 1
10103 S10_1949 26 214.3 11
10103 S10_4962 42 119.67 4
10103 S12_1666 27 121.64 8
10103 S18_1097 35 94.5 10
10103 S18_2432 22 58.34 2
10103 S18_2949 27 92.19 12
10103 S18_2957 35 61.84 14
10103 S18_3136 25 86.92 13
10103 S18_3320 46 86.31 16

It's invalid use cannot use two aggregate functions together
SELECT SUM(quantityOrdered*priceEach) AS total
FROM orderdetails od
GROUP BY orderNumber
Having SUM(quantityOrdered*priceEach)>(SELECT AVG(quantityOrdered*priceEach) FROM orderdetails)

Just calculate the average using sum() divided by a number:
SELECT SUM(quantityOrdered*priceEach) / COUNT(DISTINCT orderNumber) AS total
FROM orderdetails od ;

You do it in two steps.
SQL Fiddle Demo
Calculate the Total of each order.
SELECT orderNumber, SUM(quantityOrdered*priceEach) AS total
FROM orderdetails od
GROUP BY orderNumber
Calculate the Average between all the totals
SELECT AVG(total)
FROM ( SELECT orderNumber, SUM(quantityOrdered*priceEach) AS total
FROM orderdetails od
GROUP BY orderNumber
) T
EDIT: I miss the last step after checking Ritesh answer.
SELECT o.*, t.global_avg
FROM (SELECT orderNumber, SUM(quantityOrdered*priceEach) AS order_total
FROM orderdetails od
GROUP BY orderNumber) o
CROSS JOIN
(SELECT AVG(total) global_avg
FROM ( SELECT orderNumber, SUM(quantityOrdered*priceEach) AS total
FROM orderdetails od
GROUP BY orderNumber
) t
) t
WHERE o.order_total > t.global_avg;
OUTPUT:

Related

SUM COLUMN RESULTS 0 GROUP BY IN SUBQUERIES mysql

select cs.prod_id,
cs.product,
cs.barcode,
COALESCE(total,0) as TOTALQTY,
COALESCE(sold,0) as SOLD,
COALESCE(total-sold,0) as RMNG
from product cs left join
( select sum(totalquantity) as total,stock_id, prod_id
from stock
group by prod_id
) xx
on xx.prod_id = cs.prod_id
left join
( select sum(quantity)as sold, stock_id
from order_list
group by barcode
) yy
on yy.stock_id = xx.stock_id
inner join (
select category, cat_id
from category
) cc
on cc.cat_id=cs.cat_id
ORDER BY cs.product ASC
I tried in single query and it works sold was correct which is 48.
select barcode,sum(quantity)as SOLD, stock_id from order_list group by barcode
barcode
sold
stock_id
30055
48
457
Please help me guys. Thank you
PRODUCT TABLE
prod_id
product
barcode
58
BOX-L
30055
STOCK TABLE TOTAL QUANTITY OF THE ITEM IS 70
stock_id
prod_id
totalquantity
57
58
20
457
58
50
ORDERLIST TABLE TOTAL SOLD QUANTITY IS 48
ol_id
stock_id
barcode
quantity
3822
57
30055
20
3922
457
30055
4
3922
457
30055
4
3922
457
30055
20
|
MY OUTPUT
The result is like this. The totalQuantity is Correct but the sold and rmng is incorrect it returns 0 but it has values in a single query.
prod_id
product
barcode
TotalQuantity
SOLD
RMNG
60
BOX-L
30055
70
0
0
EXPECTED OUTPUT
prod_id
product
barcode
TotalQuantity
SOLD
RMNG
60
BOX-L
30055
70
48
22

How to sum columns from two related tables

I have two tables. Invoices and invoice_items. I am trying to get the sum of total_payment and total quantity for each client. I tried this query:
SELECT client_id,
sum(total_amount), sum(it.quantity) as days_hired
FROM `invoices` `iv`
join invoice_items it on it.invoice_id=iv.invoice_id
group by client_id, it.invoice_id
But for client_id 14, I am getting total payment as 1908 instead of 636. Looks like the sum of this column gets repeated for every invoie_item. Any help will be appreciated.
invoices
invoice_id client_id total_payment
36 13 530
38 14 636
invoice_items
invoice_id user_id quantity
36 2 2
38 3 2
38 4 2
38 5 2
Expected output:
13 530 2
14 636 6
You can try below -
SELECT client_id, sum(total_amount) as toal_amount, sum(it.quantity) as total_quantity
FROM `invoices` `iv`
join
(
select invoice_id,sum(quantity) as quantity from invoice_items group by invoice_id
)it on it.invoice_id=iv.invoice_id
group by client_id, it.invoice_id
Try:
select i.*, ii.total_quantity
from invoices i
join (
select invoice_id, sum(quantity) total_quantity from invoice_items
group by invoice_id
) ii on i.invoice_id = ii.invoice_id

select unique row as per latest created_at time

this is my query:
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC
what I am getting:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
50 pinal to prem 2016-02-19 12:20:00 73
50 prem to premal-joshi 2016-02-19 11:40:52 78
18 prem to mukund 2016-02-19 11:21:52 77
18 pinal to mukund 2016-02-18 11:37:00 76
9 mukund rate to mitesh 2016-02-15 22:34:14 51
9 Not a bad. 2016-02-10 00:16:31 45
9 sda 2016-02-08 01:36:33 39
what I want:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
Try This
SELECT rat_id,rating_comment, MAX(created_at) AS created, id FROM (
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC) AS temp GROUP BY temp.rat_id
It seems that you want only the latest record per employee_id. You can use a derived table to get the maximum date, then join again to get all fields from employee_ratings table for this date:
SELECT er.employee_id AS rat_id,
er.rating_comment,
er.created_at,
er.id
FROM employee_followers AS ef
LEFT JOIN (
SELECT employee_id, MAX(created_at) AS max_date
FROM employee_ratings
GROUP BY employee_id
) AS emp_max ON ef.employee_id = emp_max.employee_id
LEFT JOIN employee_ratings AS er
ON emp_max.employee_id = er.employee_id AND
emp_max.max_date = er.max_date
WHERE user_id = 32
ORDER BY created_at DESC
I have also removed GROUP BY br.id that seems to be redundant in the context of the query. Also IN operator can be replaced by user_id = 32 since you are selecting from the same table.

How to apply aggregate function only on distinct records

I have two tables, orders and order_item.
orders table:
Id Total DeliveryCharge Status DeliveryDate
2001 600 120 30 2015-09-01 11:56:32
2002 1500 150 30 2015-09-09 09:56:32
2003 1200 100 30 2015-09-30 08:05:32
order_item table:
Id OrderTotal Quantity
12001 2001 2
12002 2001 1
12003 2002 1
12004 2003 1
12005 2003 1
As each order can contain multiple products, that way order_item table could multiple records for a single order.
I want to get result by the query is
OrderCount Quantity OrderTotal DeliveryCharge
3 6 3300 370
I wrote a query
select count(distinct od.Id) as OrderCount,
sum(oi.Quantity) as Quantity,
(select sum(ord.OrderTotal) from orders ord
where ord.DeliveryDate between '2015-09-01' and '2015-10-01' and ord.Status=30 ) as OrderTotal
from orders od
join Order_items oi on od.Id=oi.orderId
where od.Status=30
and od.DeliveryDate between '2015-09-01' and '2015-10-01'
which has the result
OrderCount Quantity OrderTotal
3 6 3300
But now I want the sum of DeliveryCharge of orders table, so again I have to write select sub-query as I wrote for OrderTotal.
Is there a good way to find it with single query without using multiple sub-queries?
Put subqueries in the from clause:
select o.OrderCount, o.OrderTotal, o.OrderDeliveryCharge, oi.quantity
from (select count(*) as OrderCount, sum(Total) as OrderTotal,
sum(DeliveryCharge) as OrderDeliveryCharge
from orders
) o cross join
(select sum(quantity) as quantity
from order_item
) oi;
Use this
SELECT SUM(oi.oc) AS 'OrderCount', SUM(oi.q) AS 'Quantity', SUM(o.total) AS 'OrderTotal', SUM(o.deliverycharge) AS 'DeliveryCharge'
FROM
orders o INNER JOIN
(SELECT ordertotal, COUNT(DISTINCT(ordertotal)) AS oc, SUM(quantity) AS q FROM order_item GROUP BY 1) oi ON o.id=oi.ordertotal

having trouble writing a query that list all salesmen that did not sell to a particular customer

I was successful in writing the query that lists salesmen that did sell to a particular customer, but not those that have not. I suspect it is because the same salesmen that sold to the specific customer, also sold to other customers.
select a.name from salesperson a inner join orders b on
a.salesperson_id = b.salesperson_id where cust_id="4";
I was thinking that modifying the same query like this would do the trick:
.... a.salesperson_id <> b.salesperson_id where cust_id="4";
But the result lists all the salesmen. This is most likely due to the fact that the same salesmen that were returned in the original query, also sold to other customers
The 3 tables look like this:
Salesperson table
salesperson_ID, Name, Age, Salary
1 Abe 61 140000
2 Bob 34 44000
5 Chris 34 40000
7 Dan 41 52000
8 Ken 57 115000
11 Joe 38 38000
Customer table
cust_ID, Name, City Industry Type
4 faralon sacramento H
6 Apple cupertino S
7 Honda NY B
9 Kolb Oshkosh B
Orders table
Number, Order_date, cust_id, salesperson_id, Amount
10 8/2/1996 4 2 540
20 1/30/1999 4 8 1800
30 7/14/1995 9 1 460
40 1/29/1998 7 2 2400
50 2/3/1998 6 7 600
60 3/2/1998 6 7 720
70 5/6/1998 9 7 150
Any help would be greatly appreciated. ~Alpinehyker
You can do something like this:
select a.name from salesperson a
left join orders b on a.salesperson_id = b.salesperson_id and b.cust_id="4"
where b.Number is null
So, get all salepersons, left join to orders for customer 4, and return only rows where there is no such order.
I am assuming that Number is the primary key for Orders, or at least not null.
All salespeople who have NOT sold to customer_ID 4:
SELECT s.Name FROM Salesperson AS s
LEFT JOIN Orders AS o
ON s.salesperson_ID = o.salesperson_ID
WHERE o.customer_ID <> 4
GROUP BY o.salesperson_ID;
Perhaps this will work
SELECT
s.*
FROM `Salesperson` AS s
LEFT JOIN `Orders` AS o ON o.`salesperson_id` = s.`salesperson_ID`
WHERE
o.`cust_id` NOT IN (4)
GROUP BY s.`salesperson_ID`;
Answer to your 2nd question:
SELECT
COUNT(*) AS num_of_orders
,s.`Name`
FROM `Salesperson` AS s
LEFT JOIN `Orders` AS o ON o.`salesperson_id` = s.`salesperson_ID`
GROUP BY s.`salesperson_ID`
HAVING num_of_orders >= 2;
...and 3rd question. (assuming you have your highAchiever table ready)
INSERT INTO `highAchiever`
(`Name`,`Age`)
SELECT
`Name`
,`Age`
FROM `Salesperson`
WHERE
`Salary` >= 100000;