Reputation: 11
I have a base table with invoices for different stock codes, the important fields are:
StockCode | InvoiceDate |
---|---|
AAA | 2022-01-01 |
AAA | 2022-05-01 |
BBB | 2022-02-01 |
BBB | 2022-11-01 |
I am trying to work back to the cost price of those items using an amendment journal which records the changes to cost of the material. The amendment journal looks like this:
StockCode | JnlDate | Before | After |
---|---|---|---|
AAA | 2022-02-01 | 10.000 | 11.000 |
AAA | 2022-06-01 | 11.000 | 12.000 |
BBB | 2022-03-01 | 20.000 | 21.000 |
BBB | 2022-11-02 | 21.000 | 22.000 |
What I would like to do is to use OUTER APPLY to get the first amendment that occurs after the sale and get the [Before] price - which would be the price at that time. If there are no amendments after the invoice, I am able to make use of its current material cost on the system using ISNULL on the joined [Before] value.
My current code looks like this:
WITH
allChanges AS
(
-- Need to convert the varchar to numeric in the amendment journal
SELECT StockCode, JnlDate,
CONVERT(DECIMAL(18,6),REPLACE([Before],',','')) AS [Before],
CONVERT(DECIMAL(18,6),REPLACE([After],',','')) AS [After]
FROM InvMastAmendJnl
WHERE CostType = 'MaterialCost'
),
invoices AS
(
SELECT Invoice, StockCode, InvoiceDate FROM InvoiceTable
)
-- Begin query
SELECT Invoice, StockCode, InvoiceDate
FROM invoices
OUTER APPLY
(
SELECT TOP(1) [Before] AS MaterialCost
FROM allChanges
WHERE allChanges.StockCode = invoices.StockCode AND allChanges.JnlDate > invoices.InvoiceDate
ORDER BY JnlDate ASC
)
Important points:
Ultimately, what I want is a single value to return and be joined to the base table, so I need to get a single value from the outer apply for each row - what should I do?
Upvotes: 1
Views: 70
Reputation: 11
The reason that this was occurring was because of the execution plan. There is other data in the amendment journal which is not numbers and that was causing the error, despite the where clause in the cte which is only meant to get the MaterialCost.
The solution: Use a Row Goal I added the following:
SELECT TOP (1000000) StockCode, JnlDate,
CONVERT(DECIMAL(18,6),REPLACE([Before],',','')) AS [Before],
CONVERT(DECIMAL(18,6),REPLACE([After],',','')) AS [After]
FROM InvMastAmendJnl
WHERE CostType = 'MaterialCost'
Upvotes: 0