MS Access SQL Query - Joining 3 Tables to receive Total Order Price - sql

I would like to know the total price for a specific order ID. The information is contained in these tables:
Order_line_t
Order_ID Product_ID Quantity
-------- ---------- --------
1006 4 1
1006 5 2
1006 7 2
Uses_t
Product_ID Material_ID Footage
---------- ----------- -------
4 16 20
5 15 13
7 10 16
Raw_Materials_t
Material_ID Unit_Price
----------- ----------
16 05.70
15 16.72
10 15.55
The total cost is computed by
Multiplying SUM ( Order_line_t.Quantity * Uses_t.Footage * Raw_Materials_t.Unit_Price) AS Total
My current query only returns an error:
SELECT Order_line_t.Order_ID, Order_line_t.Product_ID, Uses_t.Product_ID ,Uses_t.Footage ,
SUM ( Order_line_t.Quantity * Uses_t.Footage * Raw_Materials_t.Unit_Price) AS Total
FROM Order_line_t, Uses_t , Raw_Materials_t
WHERE Order_line_t.Order_ID = 1006;
Help appreciated! How exactly do I JOIN these tables? What am i missing?

Firstly you were missing the actual joins between the tables, and secondly you were missing your group by
SELECT Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID ,
Uses_t.Footage ,
SUM ( Order_line_t.Quantity * Uses_t.Footage * Raw_Materials_t.Unit_Price) AS Total
FROM Order_line_t INNER JOIN
Uses_t ON Order_line_t.Product_ID = Uses_t.Product_ID INNER JOIN
Raw_Materials_t ON Uses_t.Material_ID = Raw_Materials_t.Material_ID
WHERE Order_line_t.Order_ID = 1006;
GROUP BY Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID ,
Uses_t.Footage
EDIT
Try this
SELECT Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID,
Uses_t.Footage,
Sum([Order_line_t].[Quantity]*[Uses_t].[Footage]*[Raw_Materials_t].[Unit_Price]) AS Total
FROM (Order_line_t INNER JOIN
Uses_t ON Order_line_t.Product_ID = Uses_t.Product_ID) INNER JOIN
Raw_Materials_t ON Uses_t.Material_ID = Raw_Materials_t.Material_ID
GROUP BY Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID,
Uses_t.Footage;
EDIT
Total by ORDER ID
SELECT Order_line_t.Order_ID,
Sum([Order_line_t].[Quantity]*[Uses_t].[Footage]*[Raw_Materials_t].[Unit_Price]) AS Total
FROM (Order_line_t INNER JOIN
Uses_t ON Order_line_t.Product_ID = Uses_t.Product_ID) INNER JOIN
Raw_Materials_t ON Uses_t.Material_ID = Raw_Materials_t.Material_ID
GROUP BY Order_line_t.Order_ID;

I think you need to compute the cost for each row, then sum the entire order. Something like:
select
Order_ID, sum(RowCost) as OrderCost
from (
select
o.Order_ID, o.Product_ID, o.Quantity,
u.Material_ID, u.Footage,
r.Unit_Price,
(o.Quantity * u.Footage * r.UnitPrice) as RowCost
from
order_line_t o INNER JOIN
uses_t u on o.Product_ID = u.Product_ID INNER JOIN
Raw_materials_t r on u.Material_ID = r.Material_ID
where
o.Order_ID = 1006
) z
group by
Order_ID

Related

How to show the count of all items in cross joined table in SQL Server

I have a table that has all Items in the inventory, table called CI
CI has 2 columns (ProdID and Price), and it looks like this
ProdID Price
-------------
A8373 700
G8745 900
J7363 300
K7222 800
Y6311 350
I have another table for documents called Docs with columns DocID, CustID and InvoiceID.
DocID, CustID, InvoiceID
------------------------
1 1001 751
2 1001 752
3 1001 753
4 1002 831
5 1002 832
6 1003 901
7 1003 902
Another table for purchases called Purchase with DocID, ProdID, ProdSize.
In the same invoice, ProdID can be repeated as it can be in different sizes
DocID, ProdID, ProdSize
------------------------
1 A8373 41
1 A8373 42
1 A8373 43
1 G8745 35
1 G8745 36
2 A8373 44
2 A8373 45
Now I want to get the quantity of of products for all customer and invoice, but for highest priced products
So it should be like this
CustID, InvoiceID, ProdID, Quantity
-----------------------------------
1001 751 A8373 3
1001 751 G8745 2
1001 751 K7222 0
1001 752 A8373 2
1001 752 G8745 0
1001 752 K7222 0
and to show 0 for the products that do not exist in that invoice
I wrote this query, but it is extremely slow. I wonder if there is an easier fast way to get this results
DECLARE #Features AS TABLE
(
CustID varchar(100),
InvoiceID varchar(100)
INDEX IX3 CLUSTERED(CustID, InvoiceID),
ProdID varchar(100),
Quantity bigint
)
INSERT INTO #Features (CustID, InvoiceID, ProdID, Quantity)
SELECT
R.CustID, R.InvoiceID, T.ProdID, COUNT(*) AS Quantity
FROM
Docs R
CROSS JOIN
(SELECT TOP 1000 * FROM CIs ORDER BY Price DESC) C
INNER JOIN
Purchase T ON T.DocID = R.DocID
GROUP BY
R.CustID, R.InvoiceID, T.ProdID
SELECT TOP 100 *
FROM #Features
ORDER BY CustID, InvoiceID, ProdID
SELECT COUNT(*) FROM #Features
UPDATE F
SET Quantity = Cnt
FROM #Features F
INNER JOIN
(SELECT R.CustID, R.InvoiceID, COUNT(*) Cnt
FROM Purchase T
INNER JOIN Docs R ON T.DocID = R.DocID
GROUP BY R.CustID, R.InvoiceID ) X ON F.CustID = X.CustID
AND F.InvoiceID = X.InvoiceID
SELECT * FROM #Features
here is a way to do this. I filter out the 1000 products first and then perform the join as follows..
Also there isn't a need for update query, all could be obtained in the SQL itself.
Filter early join late
with top_product
as (select prodid,price, rownumber() over(order by price desc) as rnk
from ci
)
,invoice_product
as(select d.docid,d.custid,d.invoiceid,p.prodid
from top_product
join docs d
on 1=1
and rnk<=1000
)
select a.CustID, a.InvoiceID, a.ProdID,count(b.prodid) as qty
from invoice_product a
left join purchase b
on a.DocID=b.docid
and a.ProdID=b.prodid
group by a.CustID, a.InvoiceID, a.ProdID
You can use the DENSE_RANK as follows:
select CustID, InvoiceID, ProdID, sum(qty) as qty
from (select d.CustID, d.InvoiceID, ci.ProdID, p.prodid as qty,
dense_rank() over (order by ci.price desc) as rn
from ci cross join docs d
left join purchase p on d.docid = p.docid and ci.prodid = p.prodid) t
where rn <= 1000
group by CustID, InvoiceID, ProdID
Can you please try following SQL Select statement where I used Common Table Expression SQL CTEs
with topproducts as (
select top 3 ProdID from CI order by Price desc
), sales as (
select
CustID,
InvoiceID,
ProdId,
count(ProdId) as cnt
from (
select
d.CustID,
d.InvoiceID,
p.ProdId
from Docs d
inner join Purchase p
on p.DocID = d.DocID
where p.ProdId in (select ProdId from topproducts)
) t1
group by
CustID,
InvoiceID,
ProdId
)
select
t.*, isnull(ss.cnt,0) as Qty
from (
select
distinct s.CustID, s.InvoiceID, p.ProdId
from sales s, topproducts p
) t
left join sales ss on ss.InvoiceID = t.InvoiceID and ss.ProdId = t.ProdId

T-SQL (Azure) table gives double results

I am trying to get a list of all the id_user and the amount of creditRecieved and the amount of creditUsed, I actually would like to add a third option that mentions the left over if any. If creditReceived is bigger as creditUsed. But the first part now doubles the outputs so I started following an explanation here on StackOverflow, but I can't get it to work.
SELECT
dbo.UserPurchase.CreditUsed,
dbo.UserCredit.CreditRecieved
FROM
(
SELECT SUM(dbo.UserPurchase.creditUsed) AS CreditUsed
FROM dbo.UserPurchase
)
dbo.UserPurchase LEFT JOIN
(
SELECT SUM(dbo.UserCredit.creditRecieved) AS CreditRecieved
FROM dbo.UserCredit
)
dbo.UserCredit ON dbo.UserPurchase.id_user = dbo.UserCredit.id_user
The data comes from these two tables
TABLE dbo.UserCredit
id id_user creditRecieved PurchasePrice
----------- ----------- -------------- -------------
1 1 150 750
2 1 25 100
3 2 65 15
TABLE dbo.UserPurchase
id id_user creditUsed date
----------- ----------- ----------- -----------
1 1 175 NULL
2 2 3 NULL
3 2 2 NULL
I would like to have the following result
id_user CreditRecieved CreditUsed CreditLeftOver
----------- -------------- ----------- --------------
1 175 175 0
2 65 5 60
Try querying each table separately:
SELECT users.id_user, coalesce(credit.received, 0) received,
coalesce(purchase.used, 0) Used, coalesce(credit.received, 0) - coalesce(purchase.used, 0) LeftOver, coalesce(purchase.purchaseCount, 0) purchaseCount
FROM
(
select distinct id_user from dbo.UserCredit
union
select distinct id_user from dbo.UserPurchase
) users
left outer join
(
select id_user, sum(creditRecieved) received from dbo.UserCredit group by id_user
) credit
on users.id_user = credit.id_user
left outer join
(
select id_user, sum(creditUsed) used, count(1) purchaseCount from dbo.UserPurchase group by id_user
) purchase
on users.id_user = purchase.id_user
Please note that there is a typo in CreditRecieved. It should be CreditReceived.
If I understand you correctly, you want the creditUsed and creditRecieved (typo on your end?) summed up by id_user? This would be the query:
SELECT p.id_user, SUM(p.creditUsed), SUM(u.creditRecieved)
FROM dbo.UserCredit u
LEFT JOIN dbo.UserPurchase p ON p.id_user = u.id_user
GROUP BY p.id_user
You can use this query
SELECT
C.id_user,
C.CreditRecieved,
P.CreditUsed,
C.CreditRecieved - P.CreditUsed CreditLeftOver
FROM
(SELECT id_user, SUM(creditRecieved) CreditRecieved FROM UserCredit GROUP BY id_user) C
LEFT JOIN
(SELECT id_user, SUM(creditUsed) CreditUsed FROM UserPurchase GROUP BY id_user) P ON C.id_user = P.id_user

sql table using sum

I would like a result of
ID received total
2 25 25
from ItemReceived table
ID item received
2 1 5
2 2 2
2 1 10
2 2 8
and ItemsToReceive table
ID item quantity
2 1 15
2 2 10
Is there a way to get this result?
I used this code:
SELECT sum(ItemsToReceive.quantity), SUM( ItemReceived.received)
FROM ItemsToReceive
INNER JOIN ItemReceived ON ItemReceived.ID = ItemsToReceive.ID
GROUP BY poitems.poid
I got a wrong result making received to 50...
Can anyone help me?
Try this
select t1.Id,t1.quantity, t2.received from
(
SELECT ID,sum(quantity) quantity from ItemsToReceive group by id
) as t1 inner join
(
SELECT ID,SUM(received) as received from ItemReceived group by id
) as t2 on t1.id=t2.id
This might help
;WITH quantity AS (
SELECT sum(ItemsToReceive.quantity) As TotQuant
,ItemsToReceive.id AS id
FROM ItemsToReceive
GROUP BY ItemsToReceive.id
), Prod As (
SELECT SUM( ItemReceived.received) As TotRec
,ItemReceived.ID As Id
FROM ItemReceived
GROUP BY ItemReceived.ID
)
SELECT
q.Id
,p.TotRec As Received
,q.TotQuant As Quantity
FROM quantity q
INNER JOIN Prod p on p.Id = q.id
select ID , sum(received) , sum(quantity) from ItemReceived left join ItemsToReceive on (ItemReceived.ID = ItemsToReceive.ID and ItemReceived.item = ItemsToReceive.item) group by ID

Count Customers based on item master

I need you to help me on writing two queries in SQL Server 2008 that shows the following information based on item master:
Brand wise count on customer master plus customer who purchased the brand
Item Wise count of customer master plus customer who purchased the item
Here the link that shows the table information and the query which I tried.
Click here to view the table in SQL Fiddle
SELECT
brandname,
division,
route,
DivisionTotalCustomersCount = MAX(DivisionTotalCustomersCount),
RouteTotalCustomersCount = MAX(RouteTotalCustomersCount),
PurchasedCustomersCount = SUM(PurchasedCustomersCount)
FROM
(SELECT
i.brandname,
c.division,
c.route,
DivisionTotalCustomersCount =
(SELECT COUNT(distinct x.CustomerID)
FROM CustomerMaster x
WHERE x.division = c.division),
RouteTotalCustomersCount =
(SELECT COUNT(distinct x.CustomerID)
FROM CustomerMaster x
WHERE x.Route = c.route),
PurchasedCustomersCount = count(distinct C.CustomerID)
FROM CustomerMaster c
LEFT OUTER JOIN SalesData s on c.CustomerID = s.CustomerID
right outer join ItemMaster i on s.item = i.itemcode
GROUP BY i.brandname, c.division, c.route) A
GROUP BY
brandname, division, route
ORDER BY 1
Result Should as below
Excelsheet
I think you need to go reconsider the report and maybe splitting it out into multiple reports.
It does not make sense to have a route count as well as a divisional count if they are counting things at different levels of aggregation. So have a route count and division count report.
Either way, division and route is going to be null for 100PLUS because there are no customers for that brand which means there is no route or division info available.
--Division Count
SELECT BrandName, Division, COUNT(CustomerMaster.CustomerID) [Customer Count]
FROM ItemMaster LEFT OUTER JOIN
SalesData ON ItemMaster.BrandName = SalesData.Brand LEFT OUTER JOIN
CustomerMaster ON SalesData.CustomerID = CustomerMaster.CustomerID
GROUP BY BrandName, Division
--Route Count
SELECT BrandName, Route, Division, COUNT(CustomerMaster.CustomerID) [Customer Count]
FROM ItemMaster LEFT OUTER JOIN
SalesData ON ItemMaster.BrandName = SalesData.Brand LEFT OUTER JOIN
CustomerMaster ON SalesData.CustomerID = CustomerMaster.CustomerID
GROUP BY BrandName, Route, Division
Using your sqlfiddle data there are 25 sales records & 18 distinct brand/ division/ route/ customer records and there are no sales invloving 100PLUS
select
B.BrandName
, V.Division
, coalesce(Brand_count,0) as Brand_count
, coalesce(Division_count,0) as Division_count
from (select distinct BrandName from ItemMaster) as B
cross join (select distinct Division from CustomerMaster) as V
left join (
select
Brand
, Division
, sum(cust_count) over (partition by Brand) as Brand_count
, sum(cust_count) over (partition by Division) as Division_count
from (
select
S.Brand
, C.Division
, count(distinct S.CustomerID) cust_count
from salesdata as S
inner join CustomerMaster as C
on S.CustomerID = C.CustomerID
inner join ItemMaster as I
on S.item = I.ItemCode
group by
S.Brand
, C.Division
) as S
) as D
on B.BrandName = D.Brand
and V.Division = D.Division
order by
B.BrandName
, V.Division
;
| BRANDNAME | DIVISION | BRAND_COUNT | DIVISION_COUNT |
|-----------|----------|-------------|----------------|
| 100PLUS | Dubai | 0 | 0 |
| 100PLUS | RAK | 0 | 0 |
| KITCO | Dubai | 9 | 11 |
| KITCO | RAK | 9 | 7 |
| Red Bull | Dubai | 9 | 11 |
| Red Bull | RAK | 9 | 7 |
http://sqlfiddle.com/#!3/fecb0/27
All Credit to #kevriley
select
A.BrandName,
B.Division,
B.Route,
B.DivisionTotalCustomers,
B.RouteTotalCustomers,
isnull(C.PurchasedCustomersCount,0) as PurchasedCustomersCount
from
(
select distinct
BrandName, Route, Division
from dbo.ItemMaster
cross join dbo.CustomerMaster
) A
join
(
select distinct
Division,
Route,
DENSE_RANK() over (partition by Division order by c.CustomerID asc) + DENSE_RANK() over (partition by Division order by c.CustomerID desc) - 1 as DivisionTotalCustomers ,
DENSE_RANK() over (partition by ROUTE order by c.CustomerID asc) + DENSE_RANK() over (partition by ROUTE order by c.CustomerID desc) - 1 as RouteTotalCustomers
from CustomerMaster c
left join SalesData s on c.CustomerID = s.CustomerID
) B on B.Division = A.Division and B.Route = A.Route
left join
(
select
s.brand,
c.division,
c.route,
PurchasedCustomersCount = count(distinct C.CustomerID)
FROM CustomerMaster c
JOIN SalesData s on c.CustomerID = s.CustomerID
--join ItemMaster i on s.item = i.itemcode
GROUP by s.brand, c.division, c.route
) C on A.Brandname = C.Brand and C.Division = A.Division and C.Route = A.Route
See the same on SQL Fiddle
Select B.Brandname,B.Division,C AS DivisionTotalCustomerCount,
ISNULL(T.Count,0) AS PURCHASEDCUSTOMERSCOUNT
from
(
Select CM.Division,M.BrandName,COUNT(distinct CM.CustomerID) AS C
from dbo.CustomerMaster CM
CROSS JOIN ItemMaster M
GROUP BY CM.Division,M.BrandName
)B
LEFT JOIN
(Select Division,Brand,COUNT(Distinct C.CustomerID) As Count from CustomerMaster C
JOIN salesdata D
On C.CustomerID=D.CustomerID
where D.Brand='Red Bull'
GROUP BY Division,Brand
)T
ON B.Brandname=T.Brand
and B.Division=T.Division
Order by 1,2

sql join query for multiple tables

I have following tables structure,
cust_info:
cust_id cust_name
1 nikhil
2 sam
bill_info:
bill_id cust_id bill_amount
7 1 10000
8 1 15000
9 2 6000
10 2 4000
paid_info:
paid_id cust_id paid_amount
11 1 5000
12 1 5000
13 2 5000
14 2 5000
now my output should display sum of bill made by customer and total amount paid by that customer and balance amount
output
cust_id total_bill total_paid balance
1 25000 10000 15000
2 10000 10000 0
where,
for example,
for cust_id = 2,
total_bill= 10000 + 15000
total_paid = 5000 + 5000
balance = total_bill - total_paid
what is convenient way to do this in sql? any sample query?
here's what i've already tried
SELECT distinct c.cust_id
, sum(b.bill_amount) as total_bill
, SUM(p.paid_amt) AS totalpaid,sum(b.bill_amount) - SUM(p.paid_amt) AS balance
FROM cust_info c
INNER JOIN bill_info b ON c.cust_id = b.cust_id
INNER JOIN paid_info p ON p.cust_id= b.cust_id group by p.cust_id;
SELECT
cust_info.cust_id,
cust_name,
bill_amount,
paid_amount,
bill_amount - paid_amount AS balance
FROM cust_info
INNER JOIN (
SELECT cust_id, SUM(bill_amount) bill_amount
FROM bill_info
GROUP BY cust_id
) bill_info ON bill_info.cust_id = cust_info.cust_id
INNER JOIN (
SELECT cust_id, SUM(paid_amount) paid_amount
FROM paid_info
GROUP BY cust_id
) paid_info ON paid_info.cust_id = cust_info.cust_id
demo
SELECT c.cust_id,
SUM(b.total_bill),
SUM(p.total_paid),
SUM(c.total_bill) - SUM(p.total_paid)
FROM
cust_info c
LEFT JOIN bill_info b ON (c.cust_id = b.cust_id)
LEFT JOIN paid_info p ON (c.cust_id = p.party_id)
GROUP
BY cust_info.cust_id
SELECT DISTINCT cust_info.cust_id,
sum(bill_amount) AS 'total_bill' ,
sum(paid_amount) AS 'total paid' ,
(SUM(bill_amount) - sum(paid_amount)) AS balance
FROM cust_info
INNER JOIN bill_info ON cust_info.cust_id = bill_info.cust_id
INNER JOIN paid_info ON cust_info.cust_id = paid_info.cust_id
GROUP BY cust_info.cust_id