0

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_BAL for the current day should be the CLOSE_BAL from the previous day
  • The CLOSE_BAL for the current day should be OPEN_BAL + 1
  • The subsequent OPEN_BAL and CLOSE_BAL should rely on the previously calculated values

For example:

  • For Day 2, the OPEN_BAL is 158 (correct), and the CLOSE_BAL should be 159
  • For Day 3, the OPEN_BAL should be 159, and the CLOSE_BAL should be 160
  • For Day 4, the OPEN_BAL should be 160, and the CLOSE_BAL should 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.

3
  • 1
    Hi - even accepting that your sample data/expected result is a simplified version of your actual data, your SQL doesn't seem to align with your data. For example, you say that the rules depend on the status (with C/F values) but your SQL seems to be using WHEN folio_no = 1 for this piece of the logic. It would be helpful if you either simplified your SQL to match your sample data or made your sample data match your SQL (i.e. include definitions and data for the Stock and FolioStatus tables) Commented Aug 16, 2024 at 9:54
  • I’ve updated to the correct query, but I’m still not getting the expected result. My challenge involves use a recursive LAG (?) function that refers to itself Commented Aug 16, 2024 at 10:34
  • is there a gap in dates? for example if right after day1 is day 5 , is it still prev_close_bal + 1 or it will be prev_close_bal + 5? Commented Aug 17, 2024 at 0:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.