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
Last activity: Feb 20, 2023, 06:54 AM