SQL get SUM, COUNT, max, min and names of invoice - sql

I have the following tables:
invoice
id
customerId
date
1
3
2020-10-10
2
NULL
2020-09-10
3
1
2020-10-15
product
id
name
price
1
car
10
2
pen
5
3
laptop
6
4
table
2
customer
id
name
1
a
2
b
3
c
4
d
invoceProduct
id
invoiceid
productid
1
1
1
3
1
2
4
1
4
5
2
2
6
2
3
I need to get the following for each invoice:
invoiceID, date, customerName, Total, Quantity(count of items), max product name and price, min product name and price in each invoice.
I wrote query and get most of values but I cannot get the name of products.
This is my sql query
WITH cte_Products(InvoiceId, date, CustomerName, ProductName, price) AS
(
select
i.id as InvoiceId,
i.date as date,
CASE
when c.name IS NULL THEN 'NoName'
Else c.name
End AS CustomerName,
p.name as ProductName,
p.price as price
from invoceProduct ip
join product p on p.id = ip.productID
join invoice i on i.id = ip.invoiceId
left join customer c on i.customerId = c.id
)
select
cte.InvoiceId,
cte.date,
cte.CustomerName,
SUM(cte.price) as Total,
count(*) AS ItemsQuantity,
MAX(cte.price) AS MostExpensiveItem,
MIN(cte.price) AS CheapestItem
from
cte_Products cte
group by cte.InvoiceId, cte.date, cte.CustomerName;
I got this result
InvoiceId
date
CustomerName
Total
ItemsQuantity
MostExpensiveItem
CheapestItem
1
2020-10-10
c
17
3
10
2
2
2020-09-10
NoName
11
2
6
5
I need to add the product name with product price under MostExpensiveItem and CheapestItem.

Related

Get ID and name of each customer and the total sum (sum of quantity of products purchased)

I'm struggling with this JOIN + SUM query
What I have are these following tables (Client, orders, product)
client_id
name
1
Frank
2
Emile
3
Rose
4
Laura
5
Samuel
order_number
client_id
product_id
units_sold
1
4
1
11
2
3
2
8
3
5
3
18
4
4
4
19
5
3
5
12
product_id
description
price
1
Rice
26.10
2
Coffee
12.50
4
Sugar
13
5
Beans
5.40
3
Milk
30.00
What I'm trying to do is generate a query that shows the ID and name of each customer and the total sum (sum of quantity of products purchased).
So far, my logic without breaking it is this:
Select
c.client_id, c.first_name
from client c
INNER JOIN orders o on o.client_id = c.client_id
I want to add the SUM part to it but whenever I try it, the new query line doesn't work
If you just want the sum of quantity of products:
SELECT c.client_id, c.first_name, SUM(o.units_sold)
FROM
client c
INNER JOIN orders o ON o.client_id = c.client_id
GROUP BY c.client_id, c.first_name;
But if you also want to see the price:
SELECT c.client_id, c.first_name, SUM(o.units_sold),
SUM(o.units_sold*p.price)
FROM
client c
INNER JOIN orders o ON o.client_id = c.client_id
INNER JOIN products p ON o.product_id = p.product_id
GROUP BY c.client_id, c.first_name;

List values per quantity and product type

I'm struggling with a task that most probably is an easy one. I want to list the client's age based on the products they have ordered - 4 bananas and 3 apples. The result should display the age column for the client who has bought a minimum of 4 bananas and 3 apples. Pineapples shouldn't be taken into consideration.
Result:
client_id age
1 10-15
Clients table:
client_id age
1 10-15
2 15-20
Products table:
product_id client_id product_name
1 1 banana
2 1 banana
3 1 banana
4 1 banana
5 1 apple
6 1 apple
7 1 apple
8 1 pineapple
9 2 apple
10 2 apple
11 2 banana
12 2 pineapple
Is this what you are looking for?
select c.*
from products p join
clients c
using (client_id)
group by c.client_id
having count(*) filter (where product_name = 'banana') >= 4 and
count(*) filter (where product_name = 'applies') >= 3;
Use group by and having:
select c.client_id, c.age
from clients c
inner join products p on p.product_id = c.client_id
where p.product_name in ('banana', 'apple')
group by c.client_id
having count(*) filter (where p.product_name = 'banana') >= 4
and count(*) filter (where p.product_name = 'apple' ) >= 3

How to write Group by in Inner Join

Here I Have Two tables:
Orders
OrderId OrderName
1 Apple
2 Mango
Cust
Id Name OrderId Price
1 John 1 50
2 John 1 100
3 Mic 1 10
4 Mic 2 10
Sql Join Query:
SELECT Orders.CustName,Items.IteamName,Orders.Price
FROM Orders JOIN Items ON Items.Id = Orders.Id
Group By
SELECT Orders.CustName, SUM(Price) FROM Orders GROUP BY Orders.CustName
How can I Write Group by in Join?
You can do like this:
Select Orders.CustName, Items.IteamName, SUM(Orders.Price)
FROM
Orders JOIN Items ON Items.Id=Orders.Id
GROUP BY
Orders.CustName, Items.IteamName
The fields that you doesn't aggregate you put at the GROUP BYclause.

Last Record Of Each Group Using Multiple Joins In Sql Server

I Have 3 tables Customer, Bank and BankTransaction.
On My View I want to display each customer with their Balance in the bank account.
Here is my tables
Customer
Id Name
---------
1 John
2 Jack
Bank
Id CustomerId BankName
----------------------------------
1 1 HSBC
2 2 HSBC
BankTransaction
Id BankID MoneyIn MoneyOut Balance
---------------------------------------------
1 1 1000 0 1000
2 1 0 500 500
3 2 2000 0 2000
4 2 2000 0 4000
5 2 1000 0 5000
Now I want to Display following data view query
John 500
Jack 5000
Last Balance of each customer
Try this
SELECT A.Name,
Sum(C.MoneyIN) - Sum(C.MoneyOut) AS Balance
FROM #Customer A
JOIN #Bank B ON A.Id = B.id
JOIN #BankTransaction C ON B.Id = C.BankID
GROUP BY A.Name
Using Window function you can get the result. Try this.
;WITH cte
AS (SELECT Row_number() OVER (partition BY b.id ORDER BY a.id DESC) rn,
c.Name,
a.balance
FROM BankTransaction a
JOIN bank b ON a.BankID = b.Id
JOIN Customer c ON c.Id = b.CustomerId)
SELECT name, balance
FROM cte
WHERE rn = 1

List orders which all rows are ready

This is my orders table. I want to report all orders which all details are Ready For Shipment.
orderNo detailNo statusId status
10001 1 40 Ready For Shipment
10002 1 40 Ready For Shipment
10002 2 20 Canceled
10002 3 30 Pending
10003 1 40 Ready For Shipment
10003 2 40 Ready For Shipment
10004 1 10 New Order
10004 2 20 Canceled
10004 3 40 Ready For Shipment
10004 4 40 Ready For Shipment
Expected results are:
Orders Ready For Shipment
10001
10003
Are there any effective method to achieve ready orders list without using subqueries?
Group by the orderno and use a havingto get only those groups having no other status
select orderno
from your_table
group by orderno
having sum(case when status <> 'Ready For Shipment' then 1 end) = 0
or with the statusId
select orderno
from your_table
group by orderno
having sum(case when statusid <> 40 then 1 end) = 0
select Distinct a.orderId
from ordersTable a
inner join
(
select orderNo, Avg(statusId)
from ordersTable
group by orderNo
having Avg(statusId) = 40) b
on a.orderNo = b.orderNo
Have you tried this?
SELECT orderNo from <TABLE NAME>
WHERE status="Ready For Shipment" ORDER BY orderNo