How can I rearrange and update a sequence of number in postgresql? - sql

In my table, each row can hold an integer let's call this integer column height.
for example, the values in this column could be: [5, 4, 0, 1, 9]
I need for this sequence in the example to be rearranged to become: [0, 1, 4, 5, 9] and then I want these values to become like this: [1, 2, 3, 4, 5].
The idea I am trying to write in SQL is to get the minimum at the first time and count how many values are there less than it.
How can I write/translate this idea into an SQL Query?

You seem to want a ranking:
select t.*, row_number() over (order by height) as height_seqnum
from t
order by height_seqnum;

Related

Find neighboring elements from circular list

I have a list as
mylist = [1, 2, 3, 4, 5, 6, 7]
I want to find the neighboring elements of any element in the list. E.g. if I select 5, I should get 4 and 6. If I select 7, I should get 6 and 1.
I found itertools.cycle as something that can help but not sure how to proceed.
Edit:
The list will be ordered or I can order it using nump sort. But there will never be repeating elements.

Determine number of preceding equal elements

Using numpy, given a sorted 1D array, how to efficiently obtain a 1D array with equal size where the value at each position is the number of preceding equal elements? I have very large arrays and processing each element in Python code one way or another is not acceptable.
Example:
input = [0, 0, 4, 4, 4, 5, 5, 5, 5, 6]
output = [0, 1, 0, 1, 2, 0, 1, 2, 3, 0]
import numpy as np
A=np.array([0, 0, 4, 4, 4, 5, 5, 5, 5, 6])
uni,counts=np.unique(A, return_counts=True)
out=np.concatenate([np.arange(n) for n in counts])
print(out)
Not certain about the efficiency (probably better way to form the out array rather than concatenating), but a very straightforward way to get the result you are looking for. Counts the unique elements, then does np.arange on each count to get the ascending sequence, then concatenates these arrays together.

Finding array position on standard SQL

SELECT 2 IN UNNEST([0, 1, 1, 2, 3, 5]) AS contains_value;
returns true, but how can we get the position?
You can return the position of the array with WITH OFFSET, but you need to move the UNNEST() to the FROM clause:
SELECT *
FROM UNNEST([0, 1, 1, 2, 3, 5]) value with OFFSET n
WHERE value = 2
You could use the With Offset as Gordon said. I was just a little slow on my typing to get the answer up.

SQL. BigQuery. Find values from an array corresponding to another column

I have a table with columns Date, UserID, EventID, Value, RangeOfValues.
The task is two determine a pair of values from the last columns between which is the value from the 4th columns. So, for example, if the user on the screenshot has value 326 in Value clmn it will be between 200 and 1000. I have a lot of users and need to extract such pairs for each of them. Can do this in python but have no ideas how to do this in bigquery (or even if it's possible).
Any advice would be appreciated!
The table looks like this
Yes, this is easily achievable using UNNEST() to turn the array into rows and then run simple sub-queries on them:
WITH test as (
SELECT * FROM UNNEST([
STRUCT(4 as value, [1, 3, 5, 7, 9, 100, 150, 40] as rangeOfValues)
,(15, [1, 3, 5, 7, 9, 100, 150, 40])
,(50, [1, 3, 5, 7, 9, 100, 150, 40])
,(160, [1, 3, 5, 7, 9, 100, 150, 40])
])
)
SELECT
value,
(SELECT MAX(r) FROM UNNEST(rangeOfValues) r WHERE r<value ) nextLowest,
(SELECT MIN(r) FROM UNNEST(rangeOfValues) r WHERE r>value ) nextBiggest
FROM test

Find records having at least one element of a given array in an array column

I use PG's array type to store some integers in a Order table:
Order
id: 1
array_column: [1, 2, 3]
id: 2
array_column: [3, 4, 5]
And I'd like to have a query returning all Orders having at least one element of a given array (let's say [3]) in array_column.
So for [3], it should return both orders since they both have 3 in array_column. For [4, 5], it should only return the second order since the first one doesn't have any element in common, and for [9, 10, 49], it shouldn't return anything.
How can I achieve this with ActiveRecord ? If it's not feasible, how can I do this using a plain SQL query ?