SQL GroupBy & InnerJoin - sql

SELECT
C.SOId, Ser.TotalService, S.TotalSales
FROM
salesorder C
INNER JOIN (SELECT SOId,SUM(charge) as TotalService FROM sales_serviceline GROUP BY SOId) Ser
ON C.SOId = Ser.SOId
INNER JOIN (SELECT SOId,SUM(PriceEach*qty) as TotalSales FROM salesline GROUP BY SOId) S
ON C.SOId = S.SOId
Explanation :
One SalesOrder has many salesline's
One SalesOrder has many salesline services's
so if a salesorder has saleslins & salesline_service then the above query successfully retrives the total amount of that salesorder but if there's only salineline or only salesline service that sales order is not retried how to change this query to get all the results ?

I think you are looking for a LEFT JOIN. If there is no rows in Ser or S then the LEFT JOIN will make TotalService or TotalSales NULL
SELECT
C.SOId, Ser.TotalService, S.TotalSales
FROM
salesorder C
LEFT JOIN (SELECT SOId,SUM(charge) as TotalService FROM sales_serviceline GROUP BY SOId) Ser
ON C.SOId = Ser.SOId
LEFT JOIN (SELECT SOId,SUM(PriceEach*qty) as TotalSales FROM salesline GROUP BY SOId) S
ON C.SOId = S.SOId
If you do not want to have them as NULL. Then you can quit easy use COALESCE(). Like this:
SELECT
C.SOId,
COALESCE(Ser.TotalService,0) AS TotalService,
COALESCE(S.TotalSales,0) AS TotalSales
FROM
salesorder C
LEFT JOIN (SELECT SOId,SUM(charge) as TotalService FROM sales_serviceline GROUP BY SOId) Ser
ON C.SOId = Ser.SOId
LEFT JOIN (SELECT SOId,SUM(PriceEach*qty) as TotalSales FROM salesline GROUP BY SOId) S
ON C.SOId = S.SOId

Related

How to select distinct items without having to use in group by clause?

I am trying to find sum of some columns using SQL like this:
select distinct c.customer,
c.customer_id,
sum(d.delay) as delay,
sum(d.delayed_amount) as delay_amt,
pd.product
from product pd
inner join mfg_company mfg on pd.product_id=mfg.product_id
inner join store s on mfg.store_id = s.store_id
inner join customer c on s.customer = c.customer_id
join delay_detail d on pd.product_id = d.material
where d.product_mfg_id = 466
group by c.customer,customer_id
order by c.customer,c.customer_id
The problem is mfg_company has duplicate product_id's(multiple mappings) ,So when I am trying to find the sum it's including those duplicates too.
Using product_id in group by clause doesn't help the result I want to see.So how to join only on distinct product_id's?
You can try below query if this helps -
select distinct c.customer
,c.customer_id
,sum(d.delay) as delay
,sum(d.delayed_amount) as delay_amt
,pd.product
from product pd
inner join (select distinct product_id
,store_id
from mfg_company) mfg on pd.product_id=mfg.product_id
inner join store s on mfg.store_id = s.store_id
inner join customer c on s.customer = c.customer_id
join delay_detail d on pd.product_id = d.material
where d.product_mfg_id = 466
group by c.customer,customer_id
order by c.customer,c.customer_id
I think the solution to your problem is to pre-aggregate the delays. It is entirely unclear if you want the product in the result set. Assuming you do not:
select c.customer, c.customer_id,
sum(d.delay) as delay, sum(d.delay_amt) as delay_amt
from product pd join
mfg_company mfg
on pd.product_id = mfg.product_id join
store s
on mfg.store_id = s.store_id
customer c
on s.customer = c.customer_id join
(select d.material, sum(d.delay) as delay, sum(d.delayed_amount) as delay_amt
from delay_detail d
group by d.material
) d
on pd.product_id = d.material
where d.product_mfg_id = 466
group by c.customer, customer_id
order by c.customer, c.customer_id;
Note that using select distinct with group by is almost never needed.

How to make, count row result and become a column -MS ACCESS QUERY

SELECT DISTINCT Customers.Name, Customers.Stall_Number, Animal_Types.Code, Count(Animal_Types.Code) AS CountOfCode, Sum(Transaction_Details.Weight) AS TotalWeight
FROM (Customers INNER JOIN Transactions ON Customers.ID = Transactions.Customer) INNER JOIN ((Animal_Types INNER JOIN Carcass ON Animal_Types.ID = Carcass.Animal_Type) INNER JOIN Transaction_Details ON Carcass.ID = Transaction_Details.Carcass) ON Transactions.ID = Transaction_Details.Transaction
GROUP BY Customers.Name, Customers.Stall_Number, Animal_Types.Code;
Please refer to images below for more details.
To get rows to become columns, you will need to use a crosstab query:
TRANSFORM Count(Animal_Types.Code)
SELECT Customers.Name, Customers.Stall_Number, Sum(Transaction_Details.Weight) AS TotalWeight
FROM (Customers INNER JOIN Transactions ON Customers.ID = Transactions.Customer) INNER JOIN ((Animal_Types INNER JOIN Carcass ON Animal_Types.ID = Carcass.Animal_Type) INNER JOIN Transaction_Details ON Carcass.ID = Transaction_Details.Carcass) ON Transactions.ID = Transaction_Details.Transaction
GROUP BY Customers.Name, Customers.Stall_Number, Animal_Types.Code
PIVOT Animal_Types.Code

SQL Select query for Select 3 different products

Good Evening,
I've been struggling with a select query on my database on which I want to determine the clients that have placed an order of 3 products from at least 3 different product categories.
Then I want to print the CustomerID and the number of the orders.
This is my Database diagram:
Any Answer would be helpful,
Sincerely Thanos.
I haven't tested this, but I believe it should be close to correct:
SELECT h.CustomerID, COUNT(DISTINCT h.SalesOrderID)
FROM SalesOrderHeader h
INNER JOIN SalesOrderDetail d1 ON h.SalesOrderID = d1.SalesOrderID
INNER JOIN SalesOrderDetail d2 ON h.SalesOrderID = d2.SalesOrderID
INNER JOIN SalesOrderDetail d3 ON h.SalesOrderID = d3.SalesOrderID
INNER JOIN Product p1 ON d1.ProductID = p1.ProductID
INNER JOIN Product p2 ON d2.ProductID = p2.ProductID
INNER JOIN Product p3 ON d3.ProductID = p3.ProductID
WHERE p1.ProductCategoryID <> p2.ProductCategoryID
AND p2.ProductCategoryID <> p3.ProductCategoryID
AND p1.ProductCategoryID <> p3.ProductCategoryID
GROUP BY h.CustomerID
select CustomerId, count(*)
from(
select CustomerId
from SalesOrderHeader soh
join SalesOrderDetail sod using (SalesOrderID)
join Product p using (ProductId)
group by CustomerId, SalesOrderId
having count(distinct ProductCategoryID) > 2
) a
group by CustomerId
I think this should get you the result
Select CustomerID,SalesOrderID , count(CategoryID) CatCount
From
SalesOrderHeader Head inner join SalesOrderDetail Det
on Head.SalesOrderID = Det.SalesOrderID
inner join Product Prod
on Prod.ProductID = Det.ProductID
inner join ProductCategory PCat
on Prod.CategoryID = PCat.CategoryID
Group By CustomerID,SalesOrderID
Having count(CategoryID) > 3
like for : "Can't solve this SQL query"
select CustomerID,count(*) as amount_of_order from
SalesOrder join
(
select SalesOrderID,count(distinct ProductCategoryID) CategoryCount
from SalesOrderDetail JOIN Product using (ProductId)
group by 1
) CatCount using (SalesOrderId)
group by 1
having bool_or(CategoryCount>=3) -- At least on CategoryCount>=3

Sql query to minus the two tables. What Is wrong?

select table1.t1 from
(
(
select
ItemCategory.Name as Category,
InventoryItems.Name as ItemName,
sum(SalesItems.Quantity) as Quantity,
(InventoryItems.Weight*sum(SalesItems.Quantity)) as Weight,
sum(SalesItems.Amount) as Amount
from SalesInvoices
inner join Sales on Sales.ID = SalesInvoices.SalesID
inner join SalesItems on SalesItems.SalesID = Sales.ID
inner join InventoryItems on InventoryItems.ID = SalesItems.InventoryItemID
inner join ItemCategory on ItemCategory.ID = InventoryItems.ItemCategoryID
inner join BusinessPartners on Sales.BusinessPartnerID = BusinessPartners.ID
where SalesInvoices.Date >= '2013-07-1' and SalesInvoices.Date <= '2013-11-7'
group by ItemCategory.Name,InventoryItems.Name,InventoryItems.Weight
) as t1,
(
select
ItemCategory.Name as Category,
InventoryItems.Name as ItemName,
sum(SalesAdjustmentItems.AdjustedQuantity)*-1 as Quantity,
(sum(SalesAdjustmentItems.AdjustedQuantity)*InventoryItems.Weight)*-1 as
Weight,
sum(SalesAdjustmentItems.AmountReturn)*-1 as Amount
from SalesInvoices
inner join Sales on Sales.ID = SalesInvoices.SalesID
inner join SalesItems on SalesItems.SalesID = Sales.ID
inner join SalesAdjustmentItems on SalesAdjustmentItems.SalesItemID = SalesItems.ID
inner join InventoryItems on InventoryItems.ID = SalesItems.InventoryItemID
inner join ItemCategory on ItemCategory.ID = InventoryItems.ItemCategoryID
inner join SalesAdustment on SalesAdustment.SalesInvoiceID = SalesInvoices.ID
inner join BusinessPartners on Sales.BusinessPartnerID = BusinessPartners.ID
where SalesAdustment.Date>= '2013-07-1' and SalesAdustment.Date <= '2013-11-7'
group by ItemCategory.Name,InventoryItems.Name,InventoryItems.Weight
) as t2
)
as table1
What I am doing wrong in this query. 1st query is for Sales and second query is for Sale returns. I want to get the difference of Sales and Returns. But is giving me error.
Thanks
The SQL minus operator is known as EXCEPT e.g. to find sales that have no invoices:
-- Sales minus SalesInvoices
SELECT ID
FROM Sales
EXCEPT
SELECT SalesID
FROM SalesInvoices;
If you are using older versions,
SELECT ID
FROM Sales
where not exists(SELECT SalesID FROM SalesInvoices where sales.ID=SalesID);

How to calculate a total of values from other tables in a column of the select statement

I have three tables:
CustOrder: id, CreateDate, Status
DenominationOrder: id, DenID, OrderID
Denomination: id, amount
I want to create a view based upon all these tables but there should be an additional column i.e. Total should be there which can calculate the sum of the amount of each order.
e.g.
order 1 total denominations 3, total amount = 250+250+250=750
order 2 total denominations 2, total amount = 250+250=500
Is it possible?
I try to guess your table relations (and data too, you did not provide any sample):
SELECT co.id,
COUNT(do.DenID) AS `Total denominations`,
SUM(d.amount) AS `Total amount`
FROM CustOrder co
INNER JOIN DenominationOrder do ON co.id = do.OrderId
INNER JOIN Denomination d ON do.DenId = d.id
GROUP BY co.id
Try this:
SELECT o.CreateDate, COUNT(o.id), SUM(d.amount) AS 'Total Amount'
FROM CustOrder o
INNER JOIN DenominationOrder do ON o.id = do.OrderID
INNER JOIN Denomination d ON do.DenId = d.id
GROUP BY o.CreateDate
DEMO
Another way to do this, by using CTE, like this:
;WITH CustomersTotalOrders
AS
(
SELECT o.id, SUM(d.amount) AS 'TotalAmount'
FROM CustOrder o
INNER JOIN DenominationOrder do ON o.id = do.OrderID
INNER JOIN Denomination d ON do.DenId = d.id
GROUP BY o.id
)
SELECT o.id, COUNT(ot.id) AS 'Orders Count', ot.TotalAmount
FROM CustOrder o
INNER JOIN CustomersTotalOrders ot on o.id = ot.id
INNER JOIN DenominationOrder do ON ot.id = do.OrderID
INNER JOIN Denomination d ON do.DenId = d.id
GROUP BY o.id, ot.TotalAmount
This will give you:
id | Orders Count | Total Amount
-------+---------------+-------------
1 3 750
2 2 500
DEMO using CTE