Sample Header Ad - 728x90

SQL Sum with break-out (audits on inventory)

2 votes
2 answers
131 views
I'm having some difficulty getting this mysql query to work. I have the following tables
create table items (
    item_id int not null auto_increment,
    item_name varchar(25),
    primary key (item_id)
);

create table types
(
    type_id int not null auto_increment,
    type_description varchar(20),
    type_val_mod int,
    primary key (type_id)
);

create table log(
    log_id int not null auto_increment,
    item_id int not null,
    log_qty int,
    log_type int not null,
    primary key (log_id)
);
default values: |type_id|type_description|type_val_mod| |-------|----------------|------------| |1 |INVOICE |1 | |2 |SALE |-1 | |3 |AUDIT |0 | and here is sample table: |log_id|item_name|type_description|log_qty|qty| |------|---------|----------------|-------|---| |2 |WIDGET A |SALE |1 |-1 | |3 |WIDGET A |SALE |3 |-3 | |4 |WIDGET A |SALE |2 |-2 | |5 |WIDGET A |INVOICE |10 |10 | |6 |WIDGET A |AUDIT |60 |0 | |7 |WIDGET A |SALE |5 |-5 | |1 |WIDGET A |INVOICE |100 |100| |11 |WIDGET B |SALE |2 |-2 | |14 |WIDGET B |SALE |5 |-5 | |13 |WIDGET B |INVOICE |60 |60 | |12 |WIDGET B |AUDIT |10 |0 | |10 |WIDGET B |SALE |1 |-1 | |9 |WIDGET B |SALE |1 |-1 | |8 |WIDGET B |INVOICE |10 |10 | |15 |WIDGET C |SALE |1 |-1 | |16 |WIDGET C |INVOICE |15 |15 | |17 |WIDGET C |SALE |1 |-1 | |18 |WIDGET C |SALE |2 |-2 | |19 |WIDGET C |AUDIT |10 |0 | |20 |WIDGET C |INVOICE |60 |60 | |21 |WIDGET C |SALE |5 |-5 | I want to have a running total column where sale subtracts from column, invoice adds to it, but audit will reset the value to whatever the audit is. So it's a conditional sum that breaks out on audit type. Likewise each item is it's own group. this is what I have so far, but I cannot get it to work and have been playing around with it for days.
with recursive rn as (
select log_id, item_name, type_description, log_qty,
 log_qty*types.type_val_mod as qty,
           row_number() over (partition by log.item_id order by log.log_id) as row_num,
           if(types.type_description="AUDIT",log_qty,null) as reset
    from log
        inner join types on log.log_type=types.type_id
        inner join items on log.item_id=items.item_id),
updated_log as(
    select log_id, item_name, type_description,row_num, log_qty, qty, reset,
           sum(if(type_description="AUDIT", 0,qty)) over (partition by item_name order by row_num rows between  0 preceding and 1 following) as new
    from rn
) select * from updated_log;
which gives: fiddle |log_id|item_name|type_description|log_qty|qty|row_num|reset|running_total| |------|---------|----------------|-------|---|-------|-----|-------------| |1 |WIDGET A |INVOICE |100 |100|1 |null |100 | |2 |WIDGET A |SALE |1 |-1 |2 |null |99 | |3 |WIDGET A |SALE |3 |-3 |3 |null |96 | |4 |WIDGET A |SALE |2 |-2 |4 |null |94 | |5 |WIDGET A |INVOICE |10 |10 |5 |null |104 | |6 |WIDGET A |AUDIT |60 |0 |6 |60 |104 | |7 |WIDGET A |SALE |5 |-5 |7 |null |99 | |8 |WIDGET B |INVOICE |10 |10 |1 |null |10 | |9 |WIDGET B |SALE |1 |-1 |2 |null |9 | |10 |WIDGET B |SALE |1 |-1 |3 |null |8 | |11 |WIDGET B |SALE |2 |-2 |4 |null |6 | |12 |WIDGET B |AUDIT |10 |0 |5 |10 |6 | |13 |WIDGET B |INVOICE |60 |60 |6 |null |66 | |14 |WIDGET B |SALE |5 |-5 |7 |null |61 | |15 |WIDGET C |SALE |1 |-1 |1 |null |-1 | |16 |WIDGET C |INVOICE |15 |15 |2 |null |14 | |17 |WIDGET C |SALE |1 |-1 |3 |null |13 | |18 |WIDGET C |SALE |2 |-2 |4 |null |11 | |19 |WIDGET C |AUDIT |10 |0 |5 |10 |11 | |20 |WIDGET C |INVOICE |60 |60 |6 |null |71 | |21 |WIDGET C |SALE |5 |-5 |7 |null |66 | any thoughts would be greatly appreciated.
Asked by Jason Chvat (23 rep)
Feb 19, 2023, 08:47 PM
Last activity: Feb 20, 2023, 06:54 AM