How to insert and update at the same time?

Could you tell me the way to realize the following in q?

As given the following table,

t:( sym:(); register_val:(); remain_val:())

[Note]

Sym is either A or B.

Type of register_val and remain_val is float.

Every time inserting a record into the table t, if values of the sym in existing record is the same as new record’s sym and remain_val is greater than 0, then subtract new record’s register_val from oldest record’s remain_val and update the table t with the result of subtraction and register the new record as it is.

For example,

  1. Initial condition

sym register_val remain_val


  1. Inset first record

sym register_val remain_val


A   1            1

  1. Insert second record

sym register_val remain_val


A   1            1

B   3            3

  1. Insert third record

sym register_val remain_val


A   1            0

B   3            3

A   1            1

  1. Insert fourth record

sym register_val remain_val


A   1            0

B   3            1

A   1            1

B   2            2

  1. Insert fitth record

sym register_val remain_val


A   1            0

B   3            0

A   1            1

B   2            0

B   3            3

Could you advise the way to realize above.

Regards

Hi,

You can write a function which updates the table in the way you want then inserts your new data, for example

f:{[x;y;z] update (remain_val:0) from (update (remain_val):remain_val-z from t where sym = x) where remain_val\<0; t insert (x;y;z)}

This function subtracts the new_remain val from the existing values in the table with the same sym, then converts any negative values to 0 and finally inserts your data into the table, e.g. if your table is

sym register_val remain_val


A   1            0

B   3            0

A   1            1

B   2            0

B   3            3

Run the function as

f[`B;4;4]

And the resulting table with look like-

sym register_val remain_val


A   1            0

B   3            0

A   1            1

B   2            0

B   3            0

B   4            4

Regards,

Lee

Hi Lee,

Thank you for your helpful advice.

In this case I have to sequentially subtract the register_val of the record to be inserted from remain_vals of existing records according to ascending order of time.

For example,

  1. Inset first record

sym register_val remain_val


A   3            3

  1. Insert second record

sym register_val remain_val


A   3            1

A   2            2

  1. Insert third record

sym register_val remain_val


A   3            0

A   2            2

A   1            1

I guess if I apply your function to this example I’ll get the following, which I won’t wish.

sym register_val remain_val


A   3            0

A   2            1

A   1            1

In addition if the register_val of the record to be inserted is greater than the full amount of existing remain_vals, all of existing remain_vals have to be update as 0.

For example,

  1. Inset first record

sym register_val remain_val


A   5            5

  1. Insert second record

sym register_val remain_val


A   5            4

A   1            1

  1. Insert third record

sym register_val remain_val


A   5            0

A   1            0

A   10           10

Regards