Add Math function to SQL Query - sql

New to SQL and I am trying to run a query that pulls all our item codes, lot number, and qty on hand.
Each lot number has multiple entries due to adjustments. I need a way of running my query and having it add or subtract to get the actual qty on hand for each lot and only show me lots that are in the negatives. I have tried playing with SSRS but I cant get it right. I'm using SQL 2008R2.
SELECT
IMLAYER.ITEM_CODE
,IMMSTR.ITEM_DESC
,IMLAYER.LOT_NO
,IMLAYER.QTY_ON_HAND
FROM
IMLAYER
INNER JOIN
IMMSTR
ON
IMLAYER.ITEM_CODE = IMMSTR.ITEM_CODE
WHERE
(IMLAYER.QTY_ON_HAND < 0);

I believe I understand the requirements correctly, but if not please comment and I can update the query:
SELECT
M.ITEM_CODE
,M.ITEM_DESC
,L.LOT_NO
,'SUM_OF_QTY_ON_HAND' = SUM(L.QTY_ON_HAND)
FROM
IMLAYER L
INNER JOIN
IMMSTR M
ON L.ITEM_CODE = M.ITEM_CODE
GROUP BY
M.ITEM_CODE
,M.ITEM_DESC
,L.LOT_NO
HAVING
SUM(L.QTY_ON_HAND) < 0
HAVING is the trick you are looking for to be able to use an aggregate function for filtering.

Related

Use group by with sum in query

These 3 tables that you see in the image are related
Course table and coaching table and sales table
I want to make a report from this table on how much each coach has sold by each course period.
The query I created is as follows, but unfortunately it has a problem and I do not know where the problem is.
Please help me fix the problem
Thank you
SELECT
dbo.tblCustomersOrders.id, dbo.tblCustomersOrders.pid, dbo.tblPost.postTitle,
dbo.tblArticleAuthor.authorName, SUM(dbo.tblCustomersOrders.prodPrice) AS TotalBuys
FROM
dbo.tblPost
INNER JOIN
dbo.tblArticleAuthor ON dbo.tblPost.id = dbo.tblArticleAuthor.articleID
INNER JOIN
dbo.tblCustomersOrders ON dbo.tblPost.id = dbo.tblCustomersOrders.pid
GROUP BY dbo.tblCustomersOrders.pid
For this use, SUM() is an Aggregate Function, so you need to refer all the
fields that you want to get in your result set.
Example:
SELECT
dbo.tblCustomersOrders.id, dbo.tblCustomersOrders.pid, dbo.tblPost.postTitle,
dbo.tblArticleAuthor.authorName, SUM(dbo.tblCustomersOrders.prodPrice) AS TotalBuys
FROM dbo.tblPost
INNER JOIN
dbo.tblArticleAuthor ON dbo.tblPost.id = dbo.tblArticleAuthor.articleID
INNER JOIN
dbo.tblCustomersOrders ON dbo.tblPost.id = dbo.tblCustomersOrders.pid
GROUP BY dbo.tblCustomersOrders.id, dbo.tblCustomersOrders.pid,
dbo.tblPost.postTitle, dbo.tblArticleAuthor.authorName
But this query does not solve the need for your report.
If you just need to get "how much each coach has sold by each course" , you can try the query bellow.
SELECT
dbo.tblArticleAuthor.authorName, dbo.tblPost.postTitle,
SUM(dbo.tblCustomersOrders.prodPrice) AS TotalBuys
FROM dbo.tblPost
INNER JOIN
dbo.tblArticleAuthor ON dbo.tblPost.id = dbo.tblArticleAuthor.articleID
INNER JOIN
dbo.tblCustomersOrders ON dbo.tblPost.id = dbo.tblCustomersOrders.pid
GROUP BY dbo.tblArticleAuthor.authorName, dbo.tblPost.postTitle
If you need, send more details regarding the desired result.
Here you can find more information about SQL SERVER Aggregate Functions:
https://learn.microsoft.com/en-us/sql/t-sql/functions/aggregate-functions-transact-sql?view=sql-server-ver15
And here a quick example regarding SQL Aliases to build queries with a simple
and effective way:
https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_alias_table
Per your description of the task, the problem is that you only GROUPed BY dbo.tblCustomersOrders.pid, which is the period's id I guess, but you also need to GROUP BY the coach, which is dbo.tblArticleAuthor.authorName, I guess again. Plus in the SELECT field list you can not use more columns only that are aggregated + GROUPed.

query replace blank

My query draws the total cost from two other queries and then adds these together to generate a job cost total. My issue is that when a job is entered and the query runs its magic in the background, dependant on the job means that one field may not contain any cost information. I believe it to be because of these empty cells that the totals do not populate correctly and thus will need to replace the blanks with £0.
https://i.stack.imgur.com/zcnk2.png
https://i.stack.imgur.com/OWJdX.png
SELECT tblMaintenanceLog.LogID, Last(QIntTotals.IntTotal) AS LastOfIntTotal, Last(QExtPartsTotalsComp.SumOfSumOfEXTPCost) AS LastOfSumOfSumOfEXTPCost, [IntTotal]+[SumOfSumOfEXTPCost] AS Expr1
FROM (tblMaintenanceLog LEFT JOIN QIntTotals ON tblMaintenanceLog.LogID = QIntTotals.INTJobID) LEFT JOIN QExtPartsTotalsComp ON tblMaintenanceLog.LogID = QExtPartsTotalsComp.EXTPJobID
GROUP BY tblMaintenanceLog.LogID, [IntTotal]+[SumOfSumOfEXTPCost]
ORDER BY tblMaintenanceLog.LogID;
I have tried an if statement to replace blanks with 0 and also the Nz function without any avail. However, I could just be entering it in wrong as I am still relatively new to VBA and SQL so any help would be greatly appreciated!
Thank you all :)
You can use COALESCE in this case.
SELECT tblMaintenanceLog.LogID , COALESCE(NULLIF(Last(QIntTotals.IntTotal),''),0) AS LastOfIntTotal, Last(QExtPartsTotalsComp.SumOfSumOfEXTPCost) AS LastOfSumOfSumOfEXTPCost, [IntTotal]+[SumOfSumOfEXTPCost] AS Expr1
FROM (tblMaintenanceLog LEFT JOIN QIntTotals ON tblMaintenanceLog.LogID = QIntTotals.INTJobID) LEFT JOIN QExtPartsTotalsComp ON tblMaintenanceLog.LogID = QExtPartsTotalsComp.EXTPJobID
GROUP BY tblMaintenanceLog.LogID, [IntTotal]+[SumOfSumOfEXTPCost]
ORDER BY tblMaintenanceLog.LogID;
I have the answer!!
Iif(Last(QIntTotals.IntTotal) is null, 0, Last(QIntTotals.IntTotal))
I cant thank you enough for your help ppijnenburg! I didn't realise how to properly add stuff in SQL until you shown me that! You have saved me much heartache!!!! Thank you :)

MS Access 2016 Error: "Multi-level group by not allowed"

i'm stuck at another point in my little Access 2016 Database. My code looks like the following and i know it probably isn't the cleanest solution but i'm kinda new to this and i tried to educate myself and get some help here already.
I'm trying to play around with the reports now a little bit and i am using this test query which returns all entries of two tables joined together.
As far as i could find out I have this one subquery included that returns the prvious day inventory for each record and that is most likely the cause of my error. I found a possible solution with adding SELECT * FROM at the beginning of my code but i get a Syntax error when i do that and i'm not sure how to solve this problem.
here's my code
SELECT Stations.StationName, Product.ProductName, GasInventoryTransactions.TransactionDate, (SELECT TOP 1 Dupe.ActualInventory FROM GasInventory AS Dupe WHERE Dupe.StationID = Stations.StationID AND Dupe.ProductID = Product.ProductID AND Dupe.InventoryDate < GasInventory.InventoryDate ORDER BY Dupe.InventoryDate DESC) AS PreviousDayInventory, GasInventory.ActualInventory, GasInventoryTransactions.GasSales, GasInventoryTransactions.GasDelivery, [PreviousDayInventory]+[GasDelivery]-[GasSales] AS BookBalance, GasInventory.ActualInventory, [ActualInventory]-[BookBalance] AS OverShort
FROM (Stations INNER JOIN (Product INNER JOIN GasInventory ON Product.[ProductID] = GasInventory.[ProductID]) ON Stations.[StationID] = GasInventory.[StationID]) INNER JOIN GasInventoryTransactions ON GasInventory.[InventoryDate] = GasInventoryTransactions.[TransactionDate];
thanks for your help!

MS Access SQL Update with Minimum

This SQL is beyond my expertise. I think it should be fairly easy for someone with experience. Here is what I have so far..
SQL is as follows:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)));
I want to add one last condition to this being that I only want the minimum of [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] to update the table. I've tried the obvious of wrapping the field in Min, and also tried creating a separate aggregate select statement first (to get the min value with other criteria) that I then tried to create the update query from in new query but no luck.
I believe this is valid Access/Jet SQL. The idea here is to use a subquery to look up the earliest date among all the rows in your subset. I'm not sure if ms_itn was the right column to correlate on but hopefully you get the idea:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID
SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)))
and [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] = (
select min(sd.[ms_start_date])
from [Tbl_Stg_Project_Schedule_Dates] as sd
where sd.ms_itn = [Tbl_Stg_Project_Schedule_Dates].ms_itn
)

SUM(a*b) not working

I have a PHP page running in postgres. I have 3 tables - workorders, wo_parts and part2vendor. I am trying to multiply 2 table column row datas together, ie wo_parts has a field called qty and part2vendor has a field called cost. These 2 are joined by wo_parts.pn and part2vendor.pn. I have created a query like this:
$scoreCostQuery = "SELECT SUM(part2vendor.cost*wo_parts.qty) as total_score
FROM part2vendor
INNER JOIN wo_parts
ON (wo_parts.pn=part2vendor.pn)
WHERE workorder=$workorder";
But if I add the costs of the parts multiplied by the qauntities supplied, it adds to a different number than what the script is doing. Help....I am new to this but if someone can show me in SQL I can modify it for postgres. Thanks
Without seeing example data, there's no way for us to know why you're query totals are coming out differently that when you do the math by hand. It could be a bad join, so you are getting more/less records than you expected. It's also possible that your calculations are off. Pick an example with the smallest number of associated records & compare.
My suggestion is to add a GROUP BY to the query:
SELECT SUM(p.cost * wp.qty) as total_score
FROM part2vendor p
JOIN wo_parts wp ON wp.pn = p.pn
WHERE workorder = $workorder
GROUP BY workorder
FYI: MySQL was designed to allow flexibility in the GROUP BY, while no other db I've used does - it's a source of numerous questions on SO "why does this work in MySQL when it doesn't work on db x...".
To Check that your Quantities are correct:
SELECT wp.qty,
p.cost
FROM WO_PARTS wp
JOIN PART2VENDOR p ON p.pn = wp.pn
WHERE p.workorder = $workorder
Check that the numbers are correct for a given order.
You could try a sub-query instead.
(Note, I don't have a Postgres installation to test this on so consider this more like pseudo code than a working example... It does work in MySQL tho)
SELECT
SUM(p.`score`) AS 'total_score'
FROM part2vendor AS p2v
INNER JOIN (
SELECT pn, cost * qty AS `score`
FROM wo_parts
) AS p
ON p.pn = p2v.pn
WHERE p2n.workorder=$workorder"
In the question, you say the cost column is in part2vendor, but in the query you reference wo_parts.cost. If the wo_parts table has its own cost column, that's the source of the problem.