Random Line From Aggregate

  

I want to return one random line from the data my aggregate retrieves.

Is there a simple way to do this without involving the forge for random number plugins?


Regards

Stijn

Hi Stijn,

There is no built-in function from the platform to generate a random number. 

If you don't want to use the forge component you can do it for instance using rand() function from sql in a sql query. 

Check this old topic with some ideias about this question: https://www.outsystems.com/forums/discussion/9890/generate-a-random-number/

Hope this helps.

Ana Reis


Ana Reis wrote:

Hi Stijn,

There is no built-in function from the platform to generate a random number. 

If you don't want to use the forge component you can do it for instance using rand() function from sql in a sql query. 

Check this old topic with some ideias about this question: https://www.outsystems.com/forums/discussion/9890/generate-a-random-number/

Hope this helps.

Ana Reis


thx for the quick reply Ana.


I did find that topic before posting the question on the forum.

They do say that it is possible to use sql to achieve it, but that it is not the best way.


Maybe I will have a look inside the forge and see what I can find that will work.


Thx for the help anyway :).

regards,

Stijn

Hi Stijn,

On the forge you can find the randomizer component: https://www.outsystems.com/forge/component/677/randomizer-number-generator/

You can use GetRandomInt action from 0 to the length of your aggregate to get a random line number. 

Regards.

Ana

Solution

Hi Stijn,

You can use this Forge component to generate a Random 

  • Generate a random With the action RandomRange (with Mininmum 0 and maximum YourAggragate.Count -1'
  • Then Get Random record from the aggragate with YourAggragate[RandomRange.Random]

Another way is to use a Advanced Query (tested with SQL Server version).

SyntaxEditor Code Snippet

select top 1 * from {YourEntity} TABLESAMPLE (1000 ROWS) order by newid()

Hope this helps (And I am curious what you are trying to do...)

Solution

Thanks for the reply Matthias.

I am going to try it in a hour or something so I will tell you if the outcome is what I expect.

The thing that I want to achieve is a sort of random matching system.

Now it only checks who has their status set on true, If it is true and not the userId of the logged in User you will get a random match. In a later more complicated version I want to use the location as an extra paramater that should match a certain range.


But the base of this matching system is that it has to be random.

I will update this topic as soon as I finish the random aggregate.


Regards,

Stijn

Hi Stijn,

You can also use the Built-in function GeneratePassword to get a random number. Just pass it the number of digits you want the number to have and make sure it doesn't generate alphanumeric passwords. For instance, the following snippet would generate a random number between 0 and 999:

TextToInteger(GeneratePassword(3,False))

If you want it to be limited to a certain value, just use the Mod Built-In function, the first argument would be the generated random number, the second one the upper bound (already not included in the range you need). For instance, if you require 2-digit numbers between A and B (including both A and B) you could do something like:

Mod(TextToInteger(GeneratePassword(2,False)), B - A + 1) + A

If you'd want 2-digit number between A and B (excluding both A and B) you could do:

Mod(TextToInteger(GeneratePassword(2,False)), B - A) + (A + 1)

Then you could use that number as an index to your Aggregate's List, like Matthias' post mentions:

YourAggregate.List[YourRandomNumber]

This way doesn't require anything other than what the platform provides directly

Problem of using a Aggragate is that the whole list must be loaded into memory before selecting it; when using a Advanced Query (also without extra extension); only 1 record (TOP 1) will be selected from the database so performance will be much better. 

The TABLESAMPLE (1000 ROWS) is also added for performance for large tables, see Limiting Result Sets by Using TABLESAMPLE