How to write a list expression with several one-to-many relationships?

I am trying to create a standard process library where processes are organized into “modules”. A module is a collection of process layers, a layer is a collection of process blocks, and a block is a collection of process steps. Steps, blocks, and layers are re-usable, so the one-to-many relationships are managed in tables called; layers_in_modules, blocks_in_layers, and steps_in_blocks.

I am trying to show ALL the steps in a process module in the module details UX by creating a virtual column with this expression, but it doesn’t work (returns no results):

SELECT(

steps[step_id],

AND(

IN([_thisrow].[mod_id], layers_in_modules[mod_id]),

IN(layers[layer_id], layers_in_modules[layer_id]),

IN(layers[layer_id], blocks_in_layers[layer_id]),

IN(blocks[block_id], blocks_in_layer[block_id]),

IN(blocks[block_id], steps_in_blocks[block_id]),

IN(steps[step_id], steps_in_blocks[step_id])

))

If this were an SQL query it would look like this.

SELECT

modules.mod_name,

layers_in_modules.lim_order as layer_number,

layers.layer_name,

blocks_in_layers.bil_order as block_number,

blocks.block_name,

steps_in_blocks.sib_order as step_number,

steps.step_short_desc,

tools.tool_name

FROM

modules,

layers,

layers_in_modules,

blocks,

blocks_in_layers,

steps,

steps_in_blocks,

tools

WHERE

layers_in_modules.mod_id = modules.mod_id AND

layers_in_modules.layer_id = layers.layer_id AND

blocks_in_layers.layer_id = layers.layer_id AND

blocks_in_layers.block_id = blocks.block_id AND

steps_in_blocks.block_id = blocks.block_id AND

steps_in_blocks.step_id = steps.step_id AND

steps.tool_id = tools.tool_id

ORDER BY

layers_in_modules.lim_order,

blocks_in_layers.bil_order,

steps_in_blocks.sib_order;

1 Like

Your table relationship is not exactly clear. But maybe you wish to take a look at the following help articles that describe AppSheet referencing including dereferencing for child, grand child tables dereferencing.

https://support.google.com/appsheet/answer/10106510?hl=en

https://support.google.com/appsheet/answer/10107396

2 Likes

Thank you for your reply. I am trying to reference a great grand child table, but in the examples it seems like dereferencing is for one-to-one relationships. Like I could maybe do something like [_thisrow].[layer_id].[block_id].[step_id] if they were connected with a simple ref, but there are the tables linking them that I don’t know what to do with.

You mentioned my table relationships are not exactly clear, so here they (simplified) are.

modules

mod_id mod_name

layers

layer_id layer_name

layers_in_modules

lim_id lim_order mod_id layer_id

blocks

block_id block_name

blocks_in_layers

bil_id bil_order layer_id block_id

steps

step_id step_short_desc

steps_in_blocks

sib_id sib_order block_id step_id

Thank you for your update. Sorry that I may not be able to suggest more as I will be away from my laptop for next few days. Of course this is a great , responsive community, so you will always get help.

Any specific reason that you have those linking tables?

A referencing directly from modules to layers to blocks to steps is not possible?

1 Like

No worries, the reason is reusability. For example, a blocks of steps might get repeated in another layer, and a layer that works well in one module might get used in another. I envision these as manufacturing processes that I will use in my work.

You’re using IN() wrong. The first argument must be a singular value, but layers[layer_id] (e.g.) is a list.

1 Like

In testing, the following returned all the rows in the layers_in_modules table.

SELECT(layers[layer_id], IN(layers[layer_id], layers_in_modules[layer_id]))

The SELECT() documentation says the second argument is “evaluated for each row of the data set” so I think in this case layers[layer_id] is a single value (eg. ‘ea36fd24’). I tried to use AND() to apply additional filters, like that the ID of the module also be in the same row of the layers_in_modules table, but it didn’t work.

Also I made a mistake in my original question, I said several “one-to-many” relationships when they are in fact many-to-many relationships. Here is the relevant part of the spec if it helps.

And my question boils down to; how to list all the steps in a module?

1 Like

Construct a list from table-column references - AppSheet Help

3 Likes

As @Steve has guided, you could build the list in stages.

Also your clarification that actually those are many to many relationships helps.

If understanding of your requirements is clear, please try

  1. In the blocks table, please add a virtual column called say, [StepsInBlocks] with an expression something like

[Related steps_in_blocks][step_id]

This will give all the steps related to each block_id

Here [Related steps_in_blocks] is the reverse reference VC in the blocks table

  1. In the layers table add a virtual column called [StepsInLayers] with an expression like

[Related blocks_in_layers][StepsInBlocks]

Here [Related blocks_in_layers] is the reverse reference VC in the blocks table.

This will give all the steps related to each layer_id

  1. In the modules table, add a virtual column called say [StepsInModules] with an expression something like

[Related layers_in_modules][StepsInLayers]

Here [Related layers_in_modules ] is the reverse reference VC in the blocks table.

This column in [StepsInModules] should give all the steps related to that module.

The above is not tested.

2 Likes

I think I’m getting closer…

Appsheet couldn’t follow the dereference in step 2, but I was able to follow your strategy and put a new virtual column in the blocks_in_layers table:

NVC_related_steps_in_blocks | [block_id].[Related steps_in_blocks]

Then in the layers table I added:

NVC_steps_in_layers | [Related blocks_in_layers][NVC_related_steps_in_blocks]

Now I get this:

The good news is I have successfully listed all the grandchildren!!! The bad news is that they are just a text list of the IDs.

Please make the column type as list with reference and point to the steps table where you are getting list of Ids.

2 Likes

That seems to have almost worked. I had to wrap my formula in SPLIT(TEXT(…)) because I was getting an error related to having a “list of a list of text” instead of a “list of text”. Now I get the following, which implies there are 41 results but none are being shown? It also seems I am getting a lot of null results that weren’t there before (see last image).

Please try using SPLIT() as

SPLIT([Related Blocks in Layers][ NYC Related…],“,”)

1 Like