I am working on SQL Server 2014. I have a query which returns a list of Job orders that will consume Components (with a required quantity ReQ) and at a specific date (Req Dt). I join this list to a stock table that provides for each component, the current available stock and the total of already reserved quantity. The job order required quantity is not yet reserved/confirmed, thus not taken into account in the stock table. The list is ordered by component number and date of need.
For each line consuming the same component, I want to add a colunm that calculates the projected Net Stock (NSt, remaining component quantity) and thus identify future missing components (when the projected Net Stock is 0 or below).
Looping into the list and for each component, the calculation rules would be :
- For the first line (first component occurence): Net Stock = (Available stock - Reserved quantity - required quantity) from the current line.
- For the second line (second component occurence): Net Stock = Net Stock from line 1 - required quantity of line 2
- For the last line: Net Stock N = Net Stock N-1 - required quantity line N
If I use Excel it would look like : enter image description here
Many thanks in advance for help on this topic.
Thanks for your interest Marc and Larnu.
I have already created the SQL code that fetches the primary data; I need to modify the query in order to add 2 columns:
- Calculation of projected Net stock (NST).
- Attribute yes/no for low remaining stock (LSt) but this one I can handle.
The table structure is mainly based on the following columns:
- Job_No=Job order that consumes the needed quantity (ReQ)
- Cmp=Component code
- Req Dt=Need Date
- ReQ=Qty needed (quantity of component needed)
- AvSt=Available Stock from stock table
- ResQ=Total reserved Qty from stock table
- NSt=Net Stock (projected remaining stock)
- LSt="If Net Stock >=0 then No, If Net Stock <0 then Yes".
Available stock and Total reserved Qty are the current values from the stock table at the moment the query is run.
For each component, the first occurence provides the initial Net Stock which is then used to calculate the Net Stock of the next occurence (line). When a new component is found, the same calculation process is restarted.
The difficult points for me are :
- How to use the calculated Net Stock value from the previous line into the current line.
- How to restart the calculation process each time a new component is found into the list.
Here are a set of data with expected results for NSt and LSt:
Job_No | Comp | Req dt | ReQ | AvSt | ResQ | NSt | LSt |
---|---|---|---|---|---|---|---|
273908 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 572 | No |
273905 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 571 | No |
273910 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 570 | No |
273909 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 569 | No |
273874 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 568 | No |
273875 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 567 | No |
273876 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 566 | No |
273881 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 565 | No |
273882 | F000307 | 03/11/2021 | 1 | 1675 | 1102 | 564 | No |
273884 | F000307 | 10/11/2021 | 1 | 1675 | 1102 | 563 | No |
274135 | F000313 | 07/09/2021 | 4 | 41688 | 6 | 41678 | No |
274136 | F000313 | 20/09/2021 | 2 | 41688 | 6 | 41676 | No |
274202 | F000314 | 14/09/2021 | 10 | 188 | 158 | 20 | No |
274203 | F000314 | 14/09/2021 | 10 | 188 | 158 | 10 | No |
274205 | F000314 | 24/09/2021 | 10 | 188 | 158 | 0 | No |
274207 | F000314 | 27/09/2021 | 10 | 188 | 158 | -10 | Yes |
274210 | F000314 | 27/09/2021 | 10 | 188 | 158 | -20 | Yes |
274211 | F000314 | 12/10/2021 | 10 | 188 | 158 | -30 | Yes |
274212 | F000314 | 21/10/2021 | 10 | 188 | 158 | -40 | Yes |
274215 | F000314 | 21/10/2021 | 10 | 188 | 158 | -50 | Yes |
274220 | F000314 | 25/10/2021 | 10 | 188 | 158 | -60 | Yes |
274222 | F000314 | 25/10/2021 | 10 | 188 | 158 | -70 | Yes |
274230 | F000314 | 25/10/2021 | 10 | 188 | 158 | -80 | Yes |
274231 | F000314 | 26/10/2021 | 10 | 188 | 158 | -90 | Yes |
--My initial SQL:
SELECT --A.[SCHN - Schedule number] 'Schedule'
A.[MFNO - Manufacturing order number] 'Job_No'
,A.[MTNO - Component number] 'Comp'
,A.[RDAT - Reservation date] 'Req dt'
,A.[REQT - Reserved quantity] 'ReQ'
,C.[STQT - On-hand balance approved] 'AvSt' -- from stock table
,C.[REQT - Reserved quantity] 'ResQ' -- from stock table
/** This is the first projected Net Stock for the first component occurence
but how to calculate the next occurence line with the previous line result? **/
,C.[STQT - On-hand balance approved]-C.[REQT - Reserved quantity]-A.[REQT - Reserved quantity] as 'NSt'
,case when (C.[STQT - On-hand balance approved]-C.[REQT - Reserved quantity]-A.[REQT - Reserved quantity])<=0 then 'Yes'
else 'No' end as 'LSt'
/* (C.[STQT - On-hand balance approved]-C.[REQT - Reserved quantity]-A.[REQT - Reserved quantity])
will be replaced by the new projected Net Stock when available*/
,A.[RGDT - Entry date]
FROM [JOB ORDERS] A
left join [WAREHOUSE STOCK] C
On A.[MTNO - Component number]=C.[ITNO - Item number] and A.[WHLO - Warehouse]=C.[WHLO - Warehouse]
where A.[WMST - Material status]<='44'
and A.[SCHN - Schedule number]<>0
and A.[RGDT - Entry date]>20210101
and A.[REQT - Reserved quantity]>0
order by A.[MTNO - Component number] ,A.[RDAT - Reservation date]
CodePudding user response:
You can use SUM
as a window function.
- Note the use of
ROWS UNBOUNDED PRECEDING
, this is necessary if theORDER BY
is non-deterministic, and is in any case more efficient - Use meaningful table aliases,
A
B
C
doesn't really help comprehension - Good whitespace formatting is essential
- Quote column names with
[]
not''
- I strongly recommend you name your columns something shorter that does not require quoting in the first place
- Date constants should be in quotes
SELECT
--jo.[SCHN - Schedule number] [Schedule]
jo.[MFNO - Manufacturing order number] [Job_No]
,jo.[MTNO - Component number] [Comp]
,jo.[RDAT - Reservation date] [Req dt]
,jo.[REQT - Reserved quantity] [ReQ]
,ws.[STQT - On-hand balance approved] [AvSt] -- from stock table
,ws.[REQT - Reserved quantity] [ResQ] -- from stock table
,SUM(ws.[STQT - On-hand balance approved] - ws.[REQT - Reserved quantity] - jo.[REQT - Reserved quantity])
OVER (PARTITION BY jo.[MTNO - Component number], jo.[WHLO - Warehouse]
ORDER BY jo.[RDAT - Reservation date] ROWS UNBOUNDED PRECEDING
) as [NSt]
,case when (ws.[STQT - On-hand balance approved] - ws.[REQT - Reserved quantity] - jo.[REQT - Reserved quantity]) <= 0
then 'Yes'
else 'No' end as [LSt]
,jo.[RGDT - Entry date]
FROM [JOB ORDERS] jo
left join [WAREHOUSE STOCK] ws
ON jo.[MTNO - Component number] = ws.[ITNO - Item number]
and jo.[WHLO - Warehouse] =ws.[WHLO - Warehouse]
where jo.[WMST - Material status] <= '44'
and jo.[SCHN - Schedule number] <> 0
and jo.[RGDT - Entry date] > '20210101'
and jo.[REQT - Reserved quantity] > 0
order by
jo.[MTNO - Component number],
jo.[RDAT - Reservation date];