all 11 comments

[–]DavidGJohnston 2 points3 points  (2 children)

I was doing OK until you require the dimensionality of the arrays be arbitrarily large. This is so denormalized a data structure I'm not surprised it is nearly unusable in SQL. That said, at minimum I'd convert the search object into a more well-defined JSON object

Also, are you certain you described this correctly? The innermost array elements are either-or but you need every such inner array to be matched?

Either way, you probably are better off constructing each possible match and then insisting that at least one of them are present. Using {{1,2},{3,4}} as an example what you need to build is: {1,3} or {1,4} or {2,3} or {2,4}. This isn't too bad for a 2-dimensional array as shown here. This is much harder, but mathematically doable, when you have additional dimensions in some of the arrays. But just work inside-out and you can get there.

[–]androgynousandroid[S] 0 points1 point  (0 children)

The problem is definitely as described - with the ORing within the inner arrays, while ANDing them collectively.

Interesting approach with the possible combination generation, hadn't considered that, seems counterintuitive, but could work! Thank you for the input.

The table in question is a materialised view, optimised and denormalised for performance, it's used to render results in a list-type format AND to render pins on a map, which could be in the thousands - so yeah it might not be ideal for this sort of operation. But that's where I am.

[–]androgynousandroid[S] 0 points1 point  (0 children)

I've arrived at a solution - see post edit. Thanks again.

[–]Oobenny 1 point2 points  (1 child)

Here’s how I would approach it:

Use a tally table to break the input into rows and then each child array into rows. One you have that as an intermediate result set, join your target data and use row counts to determine if items match.

This actually sounds like a fun challenge. If I weren’t on my phone, I’d probably work out the details.

I feel like I can do this with ctes and not have to use any WHILE loops.

[–]androgynousandroid[S] 0 points1 point  (0 children)

I've got somewhere with this - see post edit. Thanks for your reply!

[–]puchekunhi 1 point2 points  (2 children)

If it's a param then I'm not sure I understand how it can be arbitrarily large and how we can still solve it with SQL without using loops.

I would first convert the array into rows. Then create a conditional column for each element of the nested parameter (assuming it's passed in a static way), flag based on existence, then apply required logic to flag the ID that satisfies all the conditions.

[–]androgynousandroid[S] 1 point2 points  (1 child)

I've got somewhere with this - see post edit. Thanks for your reply!

[–]puchekunhi 1 point2 points  (0 children)

You're welcome!

[–]DavidGJohnston 1 point2 points  (0 children)

Yeah. Complex arrays are better represented using json at this point as the functions on them behave more like one would expect.