sqlsnowflake-cloud-data-platformcaseranking

Case to check if dates are same in a group


I have a Customer table with dataset like below:

CustID OrderDate OrderType Orig_Value
A 1/1/2025 Bulk 10
A 1/2/2025 Individual 20
B 1/3/2025 Bulk 30
B 1/3/2025 Individual 10
C 1/4/2025 Bulk 0
C 1/4/2025 Individual 5
C 1/4/2025 Other 8

I need to calculate the new column (Adj_Value) based on OrderDate for the customer.

case 1) when OrderDate is different for a customer, Adj_Value is same as Orig_Value Eg: CustID = A (in above data set)

case 2) when OrderDate is same for a customer in a group of records, Adj_Value has to be calculated based on OrderType = Bulk, when Orig_Value is not null for OrderType = Bulk Eg: CustID = B (in above data set)

case 3) when OrderDate is same for a customer in a group of records, Adj_Value has to be calculated based on OrderType = Individual, when Orig_Value is null for OrderType = Bulk Eg: CustID = C (in above data set)

Note: OrderType = "Bulk" gets preference when it is not null then "Individual" then "Other".

Here is the expected output with new filed - "Adj_Value":

CustID OrderDate OrderType Orig_Value Adj_Value
A 1/1/2025 Bulk 10 10
A 1/2/2025 Individual 20 20
B 1/3/2025 Bulk 30 30
B 1/3/2025 Individual 10 30
C 1/4/2025 Bulk 0 5
C 1/4/2025 Individual 5 5
C 1/4/2025 Other 8 5

I have tried with sql window functions, but it's not giving me the expected result:

I am not able to add the sql query here: I have attached the screenshot of the query. Please check here

Please check screenshot of SQL query here


Solution

  • You can calculate by window function values bulk_orig_value, individual_orig_value, other_orig_value
    with (partition by CustID, OrderDate).

    Then use coalesce with rule OrderType = "Bulk" gets preference when it is not null then "Individual" then "Other"
    as coalesce(Bulk_Orig_Value, Individual_Orig_value, Other_Orig_Value) Adj_Value

    To ignore 0 values use nullif(Orig_Value,0) - null if Orig_Value=0.

    select  custid,orderdate,ordertype,orig_value
      ,coalesce(Bulk_orig_Value,Individual_Orig_value,Other_Orig_Value) Adj_Value
    from(
    select *
      ,max(case when OrderType='Bulk' then nullif(Orig_Value,0) end)
           over(partition by CustID, OrderDate) Bulk_Orig_Value
      ,max(case when OrderType='Individual' then nullif(Orig_Value,0) end)
           over(partition by CustID, OrderDate) Individual_Orig_Value
      ,max(case when OrderType not in('Bulk','Individual') then nullif(Orig_Value,0) end)
           over(partition by CustID, OrderDate) Other_Orig_Value
    from customer
    )a
    
    custid orderdate ordertype orig_value adj_value
    A 2025-01-01 Bulk 10 10
    A 2025-02-01 Individual 20 20
    B 2025-03-01 Bulk 30 30
    B 2025-03-01 Individual 10 30
    C 2025-04-01 Bulk 0 5
    C 2025-04-01 Individual 5 5
    C 2025-04-01 Other 8 5

    fiddle

    With test data as

    custid orderdate ordertype orig_value
    A 2025-01-01 Bulk 10
    A 2025-02-01 Individual 20
    B 2025-03-01 Bulk 30
    B 2025-03-01 Individual 10
    C 2025-04-01 Bulk 0
    C 2025-04-01 Individual 5
    C 2025-04-01 Other 8