I have this data set:
| DAY | STATUS | OPEN_BAL | CLOSE_BAL |
|---|---|---|---|
| 1 | C | 159 | 158 |
| 2 | F | 158 | 0 |
| 3 | F | 205 | 205 |
| 4 | F | 205 | 204 |
| 5 | F | 204 | 203 |
I need to update the OPEN_BAL and CLOSE_BAL columns based on specific rules when the status is F.
The rules are as follows:
- The
OPEN_BALfor the current day should be theCLOSE_BALfrom the previous day - The
CLOSE_BALfor the current day should beOPEN_BAL + 1 - The subsequent
OPEN_BALandCLOSE_BALshould rely on the previously calculated values
For example:
- For Day 2, the
OPEN_BALis 158 (correct), and theCLOSE_BALshould be 159 - For Day 3, the
OPEN_BALshould be 159, and theCLOSE_BALshould be 160 - For Day 4, the
OPEN_BALshould be 160, and theCLOSE_BALshould be 161, and so on
Here is the sample data and the expected output:
| DAY | STATUS | UPDATED_OPEN_BAL | UPDATED_CLOSE_BAL |
|---|---|---|---|
| 1 | C | 159 | 158 |
| 2 | F | 158 | 159 |
| 3 | F | 159 | 160 |
| 4 | F | 160 | 161 |
| 5 | F | 161 | 162 |
I'm trying to achieve this with the query below, but I'm encountering issues because the LAG function only works correctly when the values in the stock table are accurate. I realize that my current solution is incorrect, but I haven't found a way to make the LAG function reference itself. Does anyone know if it's possible to do this within a SELECT query?
WITH RankedRecords AS (
SELECT
YEAR(TRY_TO_DATE(TRIM(f.open_date ), 'yymmdd')) folio_yr,
s.folio_mo, s.folio_no,
f.tt_status status,
IFNULL(try_cast(s.open_bal AS FLOAT), 0) as open_bal,
IFNULL(try_cast(s.close_book AS FLOAT), 0) as close_bal,
LAG(close_bal) OVER (ORDER BY folio_yr, fol_mo, fol_no) AS prev_close_bal
from ops_fivetran_prd_raw.azure_sql_midstreamt_us_tms6data.Stock s
join ops_fivetran_prd_raw.azure_sql_midstreamt_us_tms6data.FolioStatus f
on s.folio_mo = f.fol_mo
and s.folio_no = f.fol_no
and s.term_id = f.term_id
and upper(trim(s.term_code)) = upper(trim(f.term_code))
where s.supplier_no = '0000000000' and s.term_id = '00000BN' and folio_yr = '2024' and s.folio_mo = '08' and s.prod_id = 'MOBRED'
),
UpdatedBalances AS (
SELECT
folio_yr, folio_mo, folio_no,
status,
CASE
WHEN status = 'F' THEN prev_close_bal
ELSE open_bal
END AS expected_open_bal,
CASE
WHEN status = 'F' THEN prev_close_bal + 1
WHEN status = 'F' THEN open_bal + 1
ELSE close_bal
END AS expected_close_bal
FROM RankedRecords
),
FinalBalances AS (
SELECT
folio_yr, folio_mo, folio_no,
status,
expected_open_bal,
expected_close_bal,
LAG(expected_close_bal) OVER (ORDER BY folio_yr, folio_mo, folio_no) AS prev_expected_close_bal
FROM UpdatedBalances
)
SELECT
folio_yr, folio_mo, folio_no,
status,
CASE
WHEN status = 'F' THEN COALESCE(prev_expected_close_bal, expected_open_bal)
ELSE expected_open_bal
END AS open_bal,
expected_close_bal AS close_bal
FROM FinalBalances;
FOLIO_YR, FOLIO_MO, FOLIO_NO are represented by DAY column on the examples.