Custom sorting in sql - sql

I have a table with a column named category. the data in it is 1, 2, 3 so every row has a category.
I need sort data by category like this
1,2,3,1,2,3,1,2,3,....
then if some category finished sorting continues like this
1,2,3,1,2,3,1,3,1,3,1,1,1,1,....
I am using PostgreSQL.
thanks for your answers

You can use window functions:
order by row_number() over (partition by category order by category)
You can specify whatever you want for the order by. For instance, if you want a random ordering:
order by row_number() over (partition by category order by random())

You can use like this:
SELECT
c,
RANK () OVER (
ORDER BY c
) rank_number
FROM
ranks;
For more information: http://www.postgresqltutorial.com/postgresql-rank-function/

select ID from (
select *,row_number() over ( partition by id order by id ) rn from Yourtable
) I
order by rn,id

Related

Get last two rows from a row_number() window function in snowflake

Hopefully, someone can help me...
I'm trying to get the last two values from a row_number() window function. Let's say my results contain row numbers up to 6, for example. How would it be possible to get the rows where the row number is 5 and 6?
Let me know if it can be done with another window function or in another way.
Kind regards,
Using QUALIFY:
SELECT *
FROM tab
QUALIFY ROW_NUMBER() OVER(ORDER BY ... DESC) <= 2;
This approach could be further extended to get two rows per each partition:
SELECT *
FROM tab
QUALIFY ROW_NUMBER() OVER(PARTITION BY ... ORDER BY ... DESC) <= 2;
You can use top with order by desc like:
select top 2 row_number() over([partition by] [order by]) as rn
from table
order by rn desc
I'd say #Shmiel is the formal and elegant way, just in case, would be the same as :
WITH CTE AS
(SELECT product,
user_id,
ROW_NUMBER() OVER (PARTITION BY user_id order by product desc)
as RN
FROM Mytable)
SELECT product, user_id
FROM CTE
WHERE RN < 3;
You will use order by [order_condition] with "desc". And then you will use RN(row number) to select as many rows as you want

Is there a way to group rankings in SQL Teradata?

I am trying to get the ranking or grouping to count like in the custom_ranking column:
I want it to count the rank like in the row custom_ranking, but everything I keep trying is counting it in the current_ranking row.
I am currently using this:
,row_number() OVER (partition by custID, propID ORDER BY trans_type desc, record_date desc) AS RANKING
Based on your sample data, this would be:
dense_rank() over (partition by custid order by propid)

Generate custom group ranking in sql

As posted, I am trying to generate group ranking based on Is_True_Mod column. Here Until next 1 comes, I want 1 group to be there. Please find expected output in SQL. Here in expected output, rows grouped based on Is_True_Mode column. Regular ranking showing for reference ( order by ranking should be their )
You can identify the groups using a cumulative sum. Then you can you row_number() to enumerate the rows:
select t.*,
row_number() over (partition by grp order by regularranking) as expected_output
from (select t.*,
sum(is_true_mode) over (order by regularranking) as grp
from t
) t;

Opposite of TOP in SQL Server

I need to retrieve the last few entries from a table. I can retrieve them using:
SELECT TOP n *
FROM table
ORDER BY id DESC
That I looked everywhere and that's the only answer I could find, But that way I get them in reverse order. I need them in the same order as they are in the table because it's for a messaging interface.
Use a derived table:
select id, ...
from
(
select top n id, ...
from t
order by id desc
) dt
order by id
I suggest you to use a ROW_NUMBER() like this:
SELECT *
FROM (
SELECT
*, ROW_NUMBER() OVER (ORDER BY id DESC) AS RowNo
FROM
yourTable
) AS t
WHERE
(RowNO < #n)
ORDER BY
id

Limit result set in sql window function

Assume I would like to rewrite the following aggregate query
select id, max(hittime)
from status
group by id
using an aggregate windowing function like
select id, max(hittime) over(partition by id order by hittime desc) from status
How can I specify, that I am only interested in the first result within the partition?
EDIT: I was thinking that there might be a solution with [ RANGE | ROWS ] BETWEEN frame_start AND frame_end. What to get not only max(hittime) but also the second, third ...
I think what you need is a ranking function, either ROW_NUMBER or DENSE_RANK depending on how you want to handle ties.
select id, hittime
from (
select id, hittime,
dense_rank() over(partition by id order by hittime desc) as ranking
from status
) as x
where ranking = 1; --to get max hittime
--where ranking <=2; --max and second largest
Use distinct statement.
select DISTINCT id, max(hittime) over(partition by id order by hittime desc) from status