Sum record data into one - sql

I have this query which returns qty in each of my branch. now the branch has two WH_subType as you see in the attached diagram i have attached. I want to sum the 2 subtype and show its available qty. how can i do it.
my select query is like this
SELECT
dbo.WarehouseType.name AS Section,
dbo.WarehouseSubType.name AS WH_Type,
dbo.WarehouseSubType1.name AS WH_SubType,
dbo.Branch.name AS Branch,
(dbo.WarehouseProductQuantity.actualQuantity - dbo.WarehouseProductQuantity.reservedQuantity) AS AvailQty,
dbo.WarehouseProductQuantity.tafsilId AS Tafsil,
dbo.Tafsil.description AS Product_Name
FROM
dbo.WarehouseSubType
INNER JOIN
dbo.WarehouseType
ON
(
dbo.WarehouseSubType.warehouseTypeId = dbo.WarehouseType.id)
INNER JOIN
dbo.WarehouseSubType1
ON
(
dbo.WarehouseSubType.id = dbo.WarehouseSubType1.warehouseSubTypeId)
INNER JOIN
dbo.Warehouse
ON
(
dbo.WarehouseSubType1.id = dbo.Warehouse.warehouseSubType1Id)
INNER JOIN
dbo.Branch
ON
(
dbo.Warehouse.branchId = dbo.Branch.id)
INNER JOIN
dbo.WarehouseProductQuantity
ON
(
dbo.Warehouse.id = dbo.WarehouseProductQuantity.warehouseId)
INNER JOIN
dbo.TafsilLink
ON
(
dbo.WarehouseProductQuantity.tafsilId = dbo.TafsilLink.sourceId)
INNER JOIN
dbo.Tafsil
ON
(
dbo.TafsilLink.targetId = dbo.Tafsil.id)
INNER JOIN
dbo.FinishProduct
ON
(
dbo.Tafsil.id = dbo.FinishProduct.tafsilId)
INNER JOIN
dbo.Supplier
ON
(
dbo.FinishProduct.supplierId = dbo.Supplier.tafsilId)
WHERE
WarehouseSubType1.warehouseSubTypeId IN (1,4)
group by dbo.WarehouseProductQuantity.tafsilId

Have you tried a group by
SELECT SubType, SUM(qty) AS QtySum
GROUP BY SubType
Every grouped by column should be in your select. Note: for every column you group by it further sub divides the data
Update based on OP comment:
If you want other columns you need to do something like
SELECT s.WH_SubType,s.AvailQty, t.other_cols
from
(SELECT
dbo.WarehouseSubType1.name AS WH_SubType,
sum(dbo.WarehouseProductQuantity.actualQuantity - dbo.WarehouseProductQuantity.reservedQuantity) AS AvailQty
FROM
table
GROUP BY
dbo.WarehouseSubType1.name) s
left join table t on t.dbo.WarehouseSubType1.name = s.WH_SubType;
For reference see this question: How do I use "group by" with three columns of data?
UPDATE 2:
SELECT
dbo.WarehouseType.name AS Section,
dbo.WarehouseSubType.name AS WH_Type,
dbo.WarehouseSubType1.name AS WH_SubType,
dbo.Branch.name AS Branch,
SumTable.AvailQty,
SumTable.Tafsil,
dbo.Tafsil.description AS Product_Name
FROM
dbo.WarehouseSubType
INNER JOIN
dbo.WarehouseType
ON
(
dbo.WarehouseSubType.warehouseTypeId = dbo.WarehouseType.id)
INNER JOIN
dbo.WarehouseSubType1
ON
(
dbo.WarehouseSubType.id = dbo.WarehouseSubType1.warehouseSubTypeId)
INNER JOIN
dbo.Warehouse
ON
(
dbo.WarehouseSubType1.id = dbo.Warehouse.warehouseSubType1Id)
INNER JOIN
dbo.Branch
ON
(
dbo.Warehouse.branchId = dbo.Branch.id)
INNER JOIN
dbo.WarehouseProductQuantity
ON
(
dbo.Warehouse.id = dbo.WarehouseProductQuantity.warehouseId)
INNER JOIN
dbo.TafsilLink
ON
(
dbo.WarehouseProductQuantity.tafsilId = dbo.TafsilLink.sourceId)
INNER JOIN
dbo.Tafsil
ON
(
dbo.TafsilLink.targetId = dbo.Tafsil.id)
INNER JOIN
dbo.FinishProduct
ON
(
dbo.Tafsil.id = dbo.FinishProduct.tafsilId)
LEFT JOIN (SELECT
sum(dbo.WarehouseProductQuantity.actualQuantity - dbo.WarehouseProductQuantity.reservedQuantity) AS AvailQty,
dbo.WarehouseProductQuantity.tafsilId AS Tafsil
FROM
dbo.WarehouseProductQuantity
group by dbo.WarehouseProductQuantity.tafsilId) SumTable on dbo.Tafsil.id = SumTable.Tafsil
WHERE
WarehouseSubType1.warehouseSubTypeId IN (1,4)

You need to do something like
SELECT SUM(AvailQty), ... FROM ... WHERE ... GROUP BY WH_SubType
http://www.w3schools.com/sql/sql_func_sum.asp
http://www.w3schools.com/sql/sql_groupby.asp

Related

Update data in temporary table with new records found with joins on other table

I have data in a temporary table and I need to update this with the new data found with other tables using joins. How can I change the second select to an update statement?
Can you please suggest how to do this?
Thank you
SELECT
sc.str_psn, sc.str_esn, sc.id_smartcard, sc.id_customer, st.str_statusdesc,
pax.str_title
INTO #temp
FROM Smartrack.dbo.Smartcard sc
INNER JOIN Smartrack.dbo.Customer pax on sc.id_customer = pax.id_customer
INNER JOIN SmarTrack.dbo.StatusType st ON sc.int1_cardstatus = st.int1_statustype
SELECT
t.str_psn , t.str_esn, t.id_smartcard, t.id_customer, t.str_statusdesc,
t.str_title, subpax.datAdded, tok.str_token_desc, subpax.ultTokenType
FROM #temp t
INNER JOIN (
SELECT p.id_Customer, u.id_TravelToken, u.ultTokenType, u.datAdded, u.ultTokenExpiry
FROM SmarTrack.dbo.Customer p
INNER JOIN SmarTrack.dbo.Smartcard s ON p.id_customer = s.id_customer
INNER JOIN SmartrackInterface.dbo.vwUltimateCardDetails u ON s.id_smartcard = u.id_smartcard
WHERE s.id_replacement_smartcard IS NULL
) subpax ON t.id_customer = subpax.id_CUstomer
INNER JOIN SmarTrack.dbo.TravelToken tt ON subpax.id_TravelToken = tt.id_traveltoken
INNER JOIN SmarTrack.dbo.TokenType tok on subpax.ultTokenType = tok.int2_tokentype
Your question is similar to this: Update records in table from CTE
Your can try the following method
with cte as(
SELECT
t.str_psn , t.str_esn, t.id_smartcard, t.id_customer, t.str_statusdesc,
t.str_title, subpax.datAdded, tok.str_token_desc, subpax.ultTokenType
FROM #temp t
INNER JOIN (
SELECT p.id_Customer, u.id_TravelToken, u.ultTokenType, u.datAdded, u.ultTokenExpiry
FROM SmarTrack.dbo.Customer p
INNER JOIN SmarTrack.dbo.Smartcard s ON p.id_customer = s.id_customer
INNER JOIN SmartrackInterface.dbo.vwUltimateCardDetails u ON s.id_smartcard = u.id_smartcard
WHERE s.id_replacement_smartcard IS NULL
) subpax ON t.id_customer = subpax.id_CUstomer
INNER JOIN SmarTrack.dbo.TravelToken tt ON subpax.id_TravelToken = tt.id_traveltoken
INNER JOIN SmarTrack.dbo.TokenType tok on subpax.ultTokenType = tok.int2_tokentype
)
Update #temp
Set #temp.id_customer in (Select distinct id_customer From cte)

Access Subquery On mulitple conditions

This SQL query needs to be done in ACCESS.
I am trying to do a subquery on the total sales, but I want to link the sale to the province AND to product. The below query will work with one or the other: (po.product_name = allp.all_products) AND (p.province = allp.all_province); -- but it will no take both.
I will be including every month into this query, once I can figure out the subquery on with two criteria.
Select
p.province as [Province],
po.product_name as [Product],
all_price
FROM
(purchase_order po
INNER JOIN person p
on p.person_id = po.person_id)
left join
(
select
po1.product_name AS [all_products],
sum(pp1.price) AS [all_price],
p1.province AS [all_province]
from (purchase_order po1
INNER JOIN product pp1
on po1.product_name = pp1.product_name)
INNER JOIN person p1
on po1.person_id = p1.person_id
group by po1.product_name, pp1.price, p1.province
)
as allp
on (po.product_name = allp.all_products) AND (p.province = allp.all_province);
Make the first select sql into a table by giving it an alias and join table 1 to table 2. I don't have your table structure or data to test it but I think this will lead you down the right path:
select table1.*, table2.*
from
(Select
p.province as [Province],
po.product_name as [Product]
--removed this ,all_price
FROM
(purchase_order po
INNER JOIN person p
on p.person_id = po.person_id) table1
left join
(
select
po1.product_name AS [all_products],
sum(pp1.price) AS [all_price],
p1.province AS [all_province]
from (purchase_order po1
INNER JOIN product pp1
on po1.product_name = pp1.product_name)
INNER JOIN person p1
on po1.person_id = p1.person_id
group by po1.product_name, pp1.price, p1.province --check your group by, I dont think you want pp1.price here if you want to aggregate
) as table2 --changed from allp
on (table1.product = table2.all_products) AND (table1.province = table2.all_province);

How to use GROUP BY for a column with an alias?

I have 3 tables
tblVendor, tblVendorItem and tblEventItem.
tblEventItem has the columns Quantity and Price.
I want to show a Vendor's VendorItem on a chart based on their Sales., where Sales will be a calculated as column (Quantity * Price).
I have tried the following query but it´s not working correctly. It says: Invalid column name: Sales.
SELECT tblEventItem.Quantity * tblEventItem.Price AS 'Sales', tblEventItem.VendorItemID, tblVendorItem.Name AS 'VendorItemName'
FROM tblEventService INNER JOIN
tblEventItem ON tblEventService.EventServiceID = tblEventItem.EventServiceID INNER JOIN
tblVendorItem ON tblVendorItem.VendorItemID = tblEventItem.VendorItemID INNER JOIN
tblVendor ON tblVendorItem.VendorID = tblVendor.VendorID
WHERE (tblEventService.ServiceID = 3)
GROUP BY 'Sales'
Use CROSS APPLY or OUTER APPLY for that. This does not affect performance, however it makes code more readable and easier to use.
-- MS SQL
CREATE TABLE #test
(
b INT,
c INT
);
INSERT INTO #test VALUES (1,2), (2,3), (3,4), (4,3)
SELECT s.Sales, COUNT(*) FROM #test a CROSS APPLY (SELECT b*c AS 'Sales') s
GROUP BY s.Sales;
In your case it will be something like:
SELECT
s.Sales ,
tblEventItem.VendorItemID ,
tblVendorItem.Name AS 'VendorItemName'
FROM
tblEventService
INNER JOIN tblEventItem ON tblEventService.EventServiceID = tblEventItem.EventServiceID
INNER JOIN tblVendorItem ON tblVendorItem.VendorItemID = tblEventItem.VendorItemID
INNER JOIN tblVendor ON tblVendorItem.VendorID = tblVendor.VendorID
CROSS APPLY (SELECT tblEventItem.Quantity * tblEventItem.Price Sales) s
WHERE
( tblEventService.ServiceID = 3 )
ORDER BY
'Sales' DESC;
It is very unclear what is need to be grouped by, but hope that with this query you can do your plans.
SELECT tblVendorItem.Name, tblEventItem.Quantity * tblEventItem.Price AS 'Sale'
FROM tblEventService INNER JOIN
tblEventItem ON tblEventService.EventServiceID = tblEventItem.EventServiceID INNER JOIN
tblVendorItem ON tblEventItem.VendorItemID = tblVendorItem.VendorItemID INNER JOIN
tblVendor ON tblVendorItem.VendorID = tblVendor.VendorID
WHERE (tblEventService.VendorID =#VendorID)
GROUP BY tblVendorItem.Name,tblEventItem.Quantity, tblEventItem.Price

JOIN / LEFT JOIN conflict in SQL Server

I have a tricky query. I need to select all recent versions of 2 types of members of administrator groups. Here is the query:
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
This query will return all the administrator groups. The next step will be getting the members of these groups. Since I have 2 types of memberships (Explicit, Computed), I will have to use a LEFT JOIN to make sure that I am not excluding any rows.
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
-- The JOIN bellow can be excluded but it is here just to clarify the architecture
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN tblGroup_ComputedMember cm ON refMem.ObjectUID = cm.GroupObjectID
LEFT JOIN tblGroup_ExplicitMember em ON refMem.ObjectUID = em.GroupObjectID
The last piece in the puzzle is to get the latest version of each member. For that I will have to use JOIN to exclude older versions:
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ComputedMember
GROUP BY ObjectID
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
and
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ExplicitMember
GROUP BY ObjectID
) MostRecentEM ON MostRecentEM.MaxId = em.Id
The full query will be:
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN tblGroup_ComputedMember cm ON refMem.ObjectUID = cm.GroupObjectID
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ComputedMember
GROUP BY ObjectID
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
LEFT JOIN tblGroup_ExplicitMember em ON refMem.ObjectUID = em.GroupObjectID
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ExplicitMember
GROUP BY ObjectID
) MostRecentEM ON MostRecentEM.MaxId = em.Id
The issue is clear: The 2 JOIN to exclude old versions are also applied to the select statement and clearly no rows are returned. What would be the best solution to escape such situation and to return the intended values?
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN (
select GroupObjectID, ID, max(ID) over (partition by ObjectID) as maxID
from tblGroup_ComputedMember
) cm ON refMem.ObjectUID = cm.GroupObjectID and cm.ID = cm.maxID
LEFT JOIN (
select GroupObjectID, ID, max(ID) over (partition by ObjectID) as maxID
from tblGroup_ExplicitMember
) em ON refMem.ObjectUID = em.GroupObjectID and em.ID = em.maxID
where cm.ID = cm.MaxID
What about using LEFT join in your last two joins?
LEFT JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ComputedMember
GROUP BY ObjectID
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
And then in Where clause filter values as:
WHERE MostRecentCM.MaxId IS NOT NULL
OR
MostRecentEM.MaxId IS NOT NULL

use field in sql join where clause

I am trying to write a crystal report using a sql statement because it runs much much faster. But I am having trouble with some of the linkings. I need to use the result of a link for criteria in subsequent links.
Ok, here is a sample of what my statement looks like:
(The lines marked with ** are the lines in question)
SELECT
Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM
(
SELECT
Pub.Part.PartNum,
Pub.Part.UserChar1 AS CustID
FROM
Pub.Part
) AS Part
LEFT OUTER JOIN (
SELECT
Pub.Customer.CustID,
Pub.Customer.CustNum,
Pub.Customer.Name
FROM
Pub.Customer
WHERE
Pub.Customer.CustID = '1038'
) AS Cust
ON Part.CustID = Cust.CustID
LEFT OUTER JOIN (
SELECT
Pub.OrderDtl.PartNum,
Sum(Pub.OrderDtl.OrderQty) AS Qty
FROM
Pub.OrderHed JOIN Pub.OrderDtl ON
Pub.OrderHed.OrderNum = Pub.OrderDtl.OrderNum
WHERE
**Pub.OrderHed.CustNum = Cust.CustNum AND**
**Pub.OrderDtl.PartNum = Part.PartNum AND**
YEAR(Pub.OrderHed.OrderDate)=YEAR(CURDATE())
GROUP BY
Pub.OrderDtl.PartNum
) AS YTD ON Part.PartNum = YTD.PartNum
Now, I get an error that says:
Part.PartNum cannot be found or is not specified for the query.
I get the same error for Cust.CustNum. Will you help me figure out what I am doing wrong? Thanks!
The problem is that you are using one of the aliases, inside of a sub-query which you cannot do. You will have to do something similar to this:
SELECT Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM
(
SELECT Pub.Part.PartNum,
Pub.Part.UserChar1 AS CustID
FROM Pub.Part
) AS Part
LEFT OUTER JOIN
(
SELECT Pub.Customer.CustID,
Pub.Customer.CustNum,
Pub.Customer.Name
FROM Pub.Customer
WHERE Pub.Customer.CustID = '1038'
) AS Cust
ON Part.CustID = Cust.CustID
LEFT OUTER JOIN
(
SELECT Pub.OrderDtl.PartNum,
Sum(Pub.OrderDtl.OrderQty) AS Qty,
Pub.OrderHed.CustNum
FROM Pub.OrderHed
JOIN Pub.OrderDtl
ON Pub.OrderHed.OrderNum = Pub.OrderDtl.OrderNum
WHERE YEAR(Pub.OrderHed.OrderDate)=YEAR(CURDATE())
GROUP BY Pub.OrderDtl.PartNum, Pub.OrderHed.CustNum
) AS YTD
ON Part.PartNum = YTD.PartNum
AND Cust.CustNum = YTD.CustNum
Looking at your query more, you can actually get rid of two of the subqueries:
SELECT Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM Pub.Part Part
LEFT OUTER JOIN Pub.Customer Cust
ON Part.CustID = Cust.CustID
AND Cust.CustID = '1038'
LEFT OUTER JOIN
(
SELECT d.PartNum,
Sum(d.OrderQty) AS Qty,
h.CustNum
FROM Pub.OrderHed h
JOIN Pub.OrderDtl d
ON h.OrderNum = d.OrderNum
WHERE YEAR(h.OrderDate)=YEAR(CURDATE())
GROUP BY d.PartNum
) AS YTD
ON Part.PartNum = YTD.PartNum
AND Cust.CustNum = YTD.CustNum
This is because you can't access a parent sub-query (cust, part) within another sub-query (YTD)
However, the solution is easy in your case, filter in the ON clause instead:
SELECT
Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM
(
SELECT
Pub.Part.PartNum,
Pub.Part.UserChar1 AS CustID
FROM
Pub.Part
) AS Part
LEFT OUTER JOIN (
SELECT
Pub.Customer.CustID,
Pub.Customer.CustNum,
Pub.Customer.Name
FROM
Pub.Customer
WHERE
Pub.Customer.CustID = '1038'
) AS Cust
ON Part.CustID = Cust.CustID
LEFT OUTER JOIN (
SELECT
Pub.OrderDtl.PartNum,
Sum(Pub.OrderDtl.OrderQty) AS Qty,
Pub.OrderHed.CustNum
FROM
Pub.OrderHed JOIN Pub.OrderDtl ON
Pub.OrderHed.OrderNum = Pub.OrderDtl.OrderNum
WHERE
YEAR(Pub.OrderHed.OrderDate)=YEAR(CURDATE())
GROUP BY
Pub.OrderDtl.PartNum
) AS YTD ON Part.PartNum = YTD.PartNum AND Cust.CustNum = YTD.CustNum