SQL Server Query Count Join Table - sql

I have 2 tables are call Suppliers and Products, which products have SupplierID as foreign key.
My question is how to make a query that can show this result
Supplier Name | Total Products
--------------+---------------
Unilever | 20
Kalbe | 50
Jhonson | 70
My table structure
Suppliers => ID, Name
Products => ID, SupplierID, Brand, Price
This is what I tried:
SELECT COUNT(*) AS Total
FROM Products
GROUP BY SupplierID

select
s.Name as 'Supplier Name', count(p.ID) as 'Total Products'
from
Supliers as s
left outer join
Producsts as p on (s.Id = p.SupplierID)
group by
s.Name;

All you need in addition to your query is a sub-query to obtain the name:
SELECT COUNT(*) as Total
, (select Name from Supplier where ID = SupplierID) as [Supplier Name]
FROM Products
GROUP BY SupplierID

you can use left join by SuplierID + subquery for Products group by SuplierID to avoid multi slow query.
select T1.Name as Supplier Name
,T2.cnt as Total Product
from Supliers T1
left join (
select SuplierID,count(1) cnt
from Products
group by SuplierID
) T2 on T1.ID = T2.SuplierID

Related

Select same column from multiple tables with condition and LEFT JOIN

I have two tables with fiew similar columns :
One is for SellOrders
OrderID (PK)| id_seller| id_product| placement_date
And the other is for BuyOrders
OrderID (PK)| id_buyer| id_product| placement_date
With another table Customer concerning customers informations (Buyers and sellers)
id_customer(PK) | name_customer
And a Product table :
id(PK) | name_product
I want to write an SQL statement that will select the first placement_date when the a buy order or sell order was placed for the product and the correspending name_customer + the name_product.
I wrote a query that select the same logic but for only the selling side and I am looking to select the data for both buy and sell side :
SELECT p.name_product, s.placement_date, c.name_customer
FROM Product p
OUTER APPLY (SELECT TOP 1 placement_date, id_seller
FROM Selling
WHERE id_product = p.id
ORDER BY placement_date, OrderID ASC) s
LEFT JOIN Customer c
ON c.id_customer = s.id_seller
From what I have seen UNION SELECT seems to be the way to do this. I added UNION to the OUTER APPLY:
OUTER APPLY (SELECT TOP 1 placement_date, id_seller
FROM Selling
UNION
SELECT TOP 1 placement_date, id_buyer
WHERE id_product = p.id
ORDER BY placement_date, OrderID ASC) s
But I get stuck at the LEFT JOIN with the table Customer.
Any help ?
If I've got it right you want first of union of buy/sell orders
SELECT p.name_product, s.placement_date, c.name_customer
FROM Product p
OUTER APPLY (
SELECT TOP 1 placement_date, id_cust
FROM (
SELECT placement_date, OrderID, id_seller id_cust
FROM SellOrders
WHERE id_product = p.id
UNION
SELECT placement_date, OrderID, id_buyer
FROM BuyOrders
WHERE id_product = p.id
) t
ORDER BY placement_date, OrderID ASC
) s
LEFT JOIN Customer c
ON c.id_customer = s.id_cust

Use 1 SQL query to join 3 tables and find the category of products that generates the most revenue for each customer segment

I am using SQLite3 for this following query.
I have a table called "products" that looks like this:
I have a table called "transactions" that looks like this:
I have a table called "segments" that looks like this:
For each active segment, I want to find the category that produces the highest revenue.
I think that I know how to do this in 3 different queries.
create table table1 as
SELECT s.seg_name, p.category, t.item_qty * t.item_price as revenue
from segments s
JOIN
transactions t
on s.cust_id = t.cust_id
JOIN products p
on p.prod_id = t.prod_id
where s.active_flag = 'Y'
order by s.seg_name, p.category
;
create table table2 as
select seg_name, category, sum(revenue) as revenue
from table1
group by seg_name, category;
select seg_name, category, max(revenue) as revenue
from table2
group by seg_name;
How can I do it in 1 query?
here is one way :
select seg_name,category,revenue
from (
select
s.seg_name,
p.category,
sum(t.item_qty * t.item_price) as revenue,
rank() over (partition by seg_name order by sum(t.item_qty * t.item_price) desc) rn
from segments s
join transactions t on s.cust_id = t.cust_id
join products p on p.prod_id = t.prod_id
where s.active_flag = 'Y'
group by seg_name, p.category
) t where rn = 1

SQL Sumation from Different Tables

I would like some help on this matter.
I Have three tables.
Products Table,
Invoice Table,
Cash Table
Products Table has 2 Columns as follows (PID,BRAND)
Invoice Table has 2 columns as follows (PID,TOTALSALES)
Cash Table has 2 columns as follows (PID,TOTALSALES)
The PID's could have many different BRANDS.
for eg:
PID BRAND
1 TEST1
2 TEST2
3 TEST3
All the three tables are linked by the PID column.
i have many rows in the invoice and cash tables.
My problem is to Group the SUMMED values of the TOTALSALES in the INVOICE and CASH tables BRAND wise.
I tried using left joins but the summation value always increases when there are more than 2 table in the join.
Any help will be highly appreciated.
You can use union all and then aggregate the results from the two tables together:
select p.brand, sum(invoice_sales) as invoice_sales, sum(cash_sales) as cash_sales
from ((select pid, totalsales as invoice_sales, 0 as cash_sales
from invoice i
) union all
(select pid, 0, totalsales
from cash c
)
) ic join
product p
on ic.pid = p.id
group by p.brand;
summarise the data in the Invoice and Cash tables separately
SELECT
pr.BRAND, (ISNULL(Inv.TOTALSALES, 0.00) + ISNULL(Csh.TOTALSALES, 0.00)) TotalSales
FROM Products pr
LEFT JOIN (
SELECT
PID, SUM(TOTALSALES) TOTALSALES
FROM Invoice GROUP BY PID
) Inv ON Inv.PID = pr.PID
LEFT JOIN (
SELECT
PID, SUM(TOTALSALES) TOTALSALES
FROM Cash GROUP BY PID
) Csh ON Csh.PID = pr.PID
ORDER BY pr.BRAND
You need two separate sums for the results of joining the tables by PID values and you will need to group the records by BRAND
select sum(Invoice.TOTALSALES) as invoice_sales, sum(Cash.TOTALSALES) as cash_sales
from Products
join Invoice
on Products.PID = Invoice.PID
join Cash
on Products.PID = Cash.PID
group by Invoice.PID, Products.BRAND;
If you do not need to group by products, then just omit Invoice.PID from the group by.
another way to do it is by using subquerys
select p.*,
(select sum(i.TOTALSALES) from Invoice i where i.PID = p.PID) as TotalSalesInvoice,
(select sum(c.TOTALSALES) from Cash c where c.PID = p.PID) as TotalSalesCash
from Products p

Join data from three related tables

In Postgres I have the following 4 tables
user (
id,
name
);
order(
id,
user_id
)
service(
id,
name
);
order_to_service(
id,
order_id,
service_id
price
);
I want to write a query to see User name , amount of orders of this user and how much money he spend on all orders
Example:
name amount price
Albert 100 3200
This is my query
select u.name , count(o.user_id),sum(ots.price)
from orders o inner join users u on u.id=o.user_id
inner join order_to_service ots on ots.order_id = o.id
where(o.user_id is not null) group by u.name
This is my result:
"Аlbert";55;29978
Accodring to this result user with name Albert has 55 orders
But using this query
select count(*) from orders where user_id = (select id from users where name like 'Albert')
Result is 33
What's wrong with my first query?
If the relationship between Orders table and Order_to_service table is one to many, then you would need to sum up the price per order in Order_to_service table before joining with the Orders table. Try this:
select u.name , count(o.user_id),sum(ots.price_tot)
from orders o inner join users u on u.id=o.user_id
inner join ( select order_id, sum(price) as price_tot
from order_to_service
group by order_id ) ots
on ots.order_id = o.id
where (o.user_id is not null) group by u.name

Repeated elements counting for Sql datatables queries

I have 2 tables: an Order table and an orderDetails table.
I have written a inner join:
SELECT Order.id
FROM Order
INNER JOIN orderDetails
ON Order.id=orderDetails.id
I have got the output as:
id
100
100
100
101
101
From the above data, I want the count of each record output as:
id count
100 3
101 2
How would I do this?
Select OrderId , Count(*) as [Count]
from OrderDetials
Group By OrderId
OrderId will be a foreing key column referencing Order.Id column of Order Table
If your orderDetails.id references Order.id column This will be the query.
Select id , Count(*) as [Count]
from OrderDetials
Group By id
SELECT o.id, COUNT(*)
FROM Order o
JOIN orderDetails od ON o.id=od.id
GROUP BY o.id
You need to use the COUNT aggregate and the GROUP BY clause.
SELECT Order.id, COUNT(DISTINCT orderDetails.id)
FROM Order
INNER JOIN orderDetails ON Order.id=orderDetails.orderId
GROUP BY Order.id
It also looks like you need o alter the join condition slightly.
Use Group by
SELECT Order.id, count(*) as Count
FROM Order
INNER JOIN orderDetails
ON Order.id=orderDetails.id Group by Order.id