Is it possible to assign a `rank` from another field using a groq query - sanity

I only have a score and entrant field, but want to assign a rank based on the score value. Where scores are equal, the rank is equal, but then would skip over the next n ranks to "realign" the rank.
rank
score
entrant
1
100
"Bob"
1
100
"Jon"
3
90
"Jen"
4
80
"Jim"
At the moment I am adding the rank field with JavaScript after I get the results, but want to know if it's possible to do this with the groq query?

Related

Query smallest number of rows to match a given value threshold

I would like to create a query that operates similar to a cash register. Imagine a cash register full of coins of different sizes. I would like to retrieve a total value of coins in the fewest number of coins possible.
Given this table:
id
value
1
100
2
100
3
500
4
500
5
1000
How would I query for a list of rows that:
has a total value of AT LEAST a given threshold
with the minimum excess value (value above the threshod)
in the fewest possible rows
For example, if my threshold is 1050, this would be the expected result:
id
value
1
100
5
1000
I'm working with postgres and elixir/ecto. If it can be done in a single query great, if it requires a sequence of multiple queries no problem.
I had a go at this myself, using answers from previous questions:
Using ABS() to order by the closest value to the threshold
Select rows until a sum reduction of a single column reaches a threshold
Based on #TheImpaler's comment above, this prioritises minimum number of rows over minimum excess. It's not 100% what I was looking for, so open to improvements if anyone can, but if not I think this is going to be good enough:
-- outer query selects all rows underneath the threshold
-- inner subquery adds a running total column
-- window function orders by the difference between value and threshold
SELECT
*
FROM (
SELECT
i.*,
SUM(i.value) OVER (
ORDER BY
ABS(i.value - $THRESHOLD),
i.id
) AS total
FROM
inputs i
) t
WHERE
t.total - t.value < $THRESHOLD;

Retrieve from the database rows ordered by a boolean column, but also random as a second criterion

I have an Items table:
id | name | is_featured
1 name1 false
The items from this table I need to show them in a random way, but is_featured first. The rules are:
If count is_featured=True > 6, get is_featured=True all, and randomize and get first 6
If count is_featured=True < 6, get is_featured=True all, and randomize
Count how many are missing up to 6. Get from non-featured random the remaining items.Unite lists.
I do this in 2-3 steps in database:
first count the number of featured
first get featured then get the rest if is needed, and randomize(in backend)
It is possible to do that in one step, in database?
You seem to want six rows, with the is_featured first. You can do this in one step:
select i.*
from items i
order by i.is_featured desc, -- true is first
random()
fetch first 6 rows only;
That is, sort all the data with is_featured first. Then choose the first six.

Selecting TOP ranking through SQL in Unica

I have a table with 2 columns; sub_ID and RANK.
All sub_ID are unique and there are around 100k and have all been given a RANK between 1 - 38 in the RANK column.
I am working in Unica or IBM Campaign where in a SELECT cell I need to enter raw SQL that only returns 5000 subscribers where it selects based on the RANK in preference for 38 and less.
Use a sample process box. Limiting number of cells to 1 with number of records to 5000 and sorting based on rank column

SQL field constraint that forces a column to be ascending

I am working on a small table that has a user input with a number field. The number that the user inputs has to be larger by a few points than the current highest number. Can I also check that the score has to be for instance 1 higher if the current highest score is < 10 but 5 higher if the current highest 10 <= score < 100?
for instance:
user score
1 1
1 2
1 4
1 5
1 7
Now, I want a constraint that will check on insert that the inserted score is bigger than the current highest score by x amount.
Is such a constraint possible?
Such a constraint is difficult to implement. If you care about performance, can you simply input the difference?
1 1
1 1
1 2
1 1
1 2
If you do the data this way, then you can use check (score > 0) and then use sum(score) over (order by ??), where ?? specifies the ordering of the rows.
Otherwise, you'll need to use either a trigger or user-defined function to implement the constraint.

Getting player rank from database

I have a RuneScape private server, which stores the player scores in a database.
The highscores load the player's scores and put them into a table.
But now comes the harder part I can't fix:
I want to display the rank of the player. Like: 'Attack level: 44, ranked 12'. So it has to find the rank the user has.
How can I get this to work? I googled for 2 days now, I did not find anything.
I don't know if there's a way to achieve this using the same query.
You could make another query like:
pos = select count(*) from players where attack > 44 + 1
This query would return the number of players ranked above someone. The "plus one" part is to make the rank start at 1 (because the first one won't have anyone ranked above him).
For example, if the table is:
id attack
0 35
1 22
2 121
3 76
pos(3) = 1 (only player 2 is ranked above) + 1 = 2
You can create a view (probably) that shows every players score. Something along these lines might work.
create view player_scores as
select player_id, sum(score)
from scores
group by player_id
That will give you one row per player, with their total score. Having that view, the rank is simple.
select count(*)
from player_scores
where sum > (select sum from player_scores where player_id = 1)
That query will return the number of players having a higher score than player_id = 1.
Of course, if you know your player's score before you run the query, you can pass that score as a parameter. That will run a lot faster as long as the column is indexed.