How to group numbered rows into groups - sql

In Sql Server I need to take repeating sets of row numbers and group those into segments or sub groups. I'm trying to achieve column B using Sql. I've achieved column a using the row_number() function but I'm not sure how to get to Column B.
Here is the logic for row_number()
1 + ((row_number() over (order by TimeStamp, FileName, OrderID) - 1) % 5) AS [Row_Number]

Your row_number() is of the form:
row_number() over (partition by colA order by colB)
What you seem to want is:
dense_rank() over (order by colA)
That is, the partition key(s) used for the row_number() should be the order by keys for the dense_rank().
EDIT:
Your code is:
1 + ((row_number() over (order by TimeStamp, FileName, OrderID) - 1) % 5) AS [Row_Number]
In this case, there is no partition by. What you really want simply integer division. This is easy:
1 + ((row_number() over (order by TimeStamp, FileName, OrderID) - 1) / 5) AS [Row_Number]

I would go with a simple solution:
SELECT [Row_Number], GroupNumber
FROM (
SELECT [Row_Number]
, row_number()over(partition by [Row_Number] order by [Row_Number]) as GroupNumber
--Note: The order by clause above should be replaced with however you are ordering the groups of row numbers)
FROM YourTableOrInlineView
) z
ORDER BY GroupNumber, [Row_Number]

Related

How to increment the dense rank based on condition

Below enclosed is my requirement.
I want to increment the dense rank function with the cap of each 5 line items by the partition of seller_state and warehouse_id code. for more clarification I have attached sample data of my requirement kindly help me on same.
below mentioned queries are my tries.
CASE
WHEN icta_amount < 0 THEN (DENSE_RANK() OVER (PARTITION BY seller_state ORDER BY seller_state,warehouse_id)) % 5
WHEN icta_amount >= 0 THEN (DENSE_RANK() OVER (PARTITION BY seller_state ORDER BY seller_state,warehouse_id))% 5
END AS DENSE_RANK,
if i add warehouse_id in partition clause in all the places i am getting only 1 don't know the meaning of that.
Thank you in advance.
I'd start with a row_number partitioned by the seller_state and warehouse_id, floor that into groups of five, and then dense_rank over it:
SELECT seller_state, warehouse_id,
DENSE_RANK() OVER (PARTITION BY seller_state, warehouse_id
ORDER BY seller_state, warehouse_id, FLOOR((rn - 1) / 5.0))
FROM (SELECT seller_state, warehouse_id,
ROW_NUMBER() OVER (PARTITION BY seller_state, warehouse_id) AS RN
FROM mytable) t
SQLFiddle demo
If you prefer to use dense_rank() then you'd want to use integer division to mark off the blocks:
with data as (
select seller_state, warehouse_id,
row_number() over (partition by seller_state, warehouse_id
order by seller_state, warehouse_id) as rn
from T
)
select seller_state, warehouse_id,
dense_rank() over (order by seller_state, warehouse_id, (rn - 1) / 5) as rnk
from data;
You could also mark the spots where the counter should increase and them accumulate them. Count off each of the rows in the same state and warehouse. When you find one with where row number mod 5 = 1 mark it as step for your ranking counter. This will immediately reset on a change of state or warehouse as desired:
sum(case when rn % 5 = 1 then 1 end)
over (order by seller_state_warehouse_id, rn) as rnk
Some platforms do not require the order by where it is simply repeating the partition by columns while others do.
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=d32dba8fccbfb8b85a7eb26f4c8f4849

Hive/Spark Repeat Dense Rank N Times

I have a table and I need to repeat the rank/dense rank value n times. Ive seen some posts where the numbering restarts by some partition but for my case I do not have a column I am partitioning.
I am looking for something like this
This is how I have my code currently
WITH d_rank_tbl AS(
SELECT
id,
1+ (dense_rank() over (order by id) - 1) % 10 as d_rank
FROM id_bucket)
SELECT
id,
dense_rank() over (partition by d_rank order by rand())
FROM d_rank_tbl
How about arithmetic instead?
select t.*,
floor((row_number() over (order by id) + 2) / 3) as d_rank
from id_bucket;
The + 2 is so the numbering starts at 1 instead of 0.

I want to generate continuously number by 2 column and batch wise

I want to generate continuously number with the combination of 2 columns and in batch size of 5. Anybody can help to solve this?
An adoption of #GordonLinoff's answer...
SELECT
name,
rank,
DENSE_RANK() OVER (ORDER BY name DESC, Rank, ((seqnum - 1) / 5)) AS rno
FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY name, rank ORDER BY (SELECT null)) AS seqnum
FROM
yourTable
)
sequenced
ORDER BY
3
You can use row_number() and arithmetic:
select name, rank,
((seqnum - 1) / 5) + 1 as rno
from (select t.*,
row_number() as (partition by name, rank order by (select null)) as seqnum
from t
) t
order by seqnum;

SQL Finding five largest numbers instead of one Max in a table

I have a table and I need to run a query that contains some aggregation Functions like Maximum , Average , Standard Deviation , ...
but instead of one Maximum I should return 5 largest number.
the simplified query is something like this:
SELECT OSI_KEY , MAX(VALUE) , AVG(VALUE) , STDDEV(VALUE), variance(VALUE)
FROM DATA_VALUES_5MIN_6_2013
GROUP BY OSI_KEY
ORDER BY OSI_KEY
and I need some Magical ;) Query like this:
SELECT OSI_KEY , MAX1(VALUE) ,MAX2(VALUE) ,MAX3(VALUE) ,MAX4(VALUE) , MAX5(VALUE) ,
AVG(VALUE) , STDDEV(VALUE), variance(VALUE)
FROM DATA_VALUES_5MIN_6_2013
GROUP BY OSI_KEY
ORDER BY OSI_KEY
I appreciate your considerations.
Oracle has an NTH_VALUE() function. Unfortunately, it is only an analytic function and not a window function. This leads to the strange construct of SELECT DISTINCT with a bunch of analytic functions:
SELECT DISTINCT OSI_KEY,
MAX(VALUE) OVER (PARTITION BY OSI_KEY),
NTH_VALUE(VALUE, 2) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_2,
NTH_VALUE(VALUE, 3) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_3,
NTH_VALUE(VALUE, 4) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_4,
NTH_VALUE(VALUE, 5) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_5,
AVG(VALUE) OVER (PARTITION BY OSI_KEY),
STDDEV(VALUE) OVER (PARTITION BY OSI_KEY),
variance(VALUE) OVER (PARTITION BY OSI_KEY)
FROM DATA_VALUES_5MIN_6_2013
ORDER BY OSI_KEY;
You can also do this using conditional aggregation, with a row_number() or dense_rank() in a subquery.
SELECT OSI_KEY, MaxValue FROM (
SELECT OSI_KEY, MAX(value) AS MaxValue FROM table GROUP BY OSI_KEY
)
ORDER BY MaxValue DESC
FETCH FIRST 5 ROWS ONLY;

Ranking Over Row_Number in SQL

I am posting a sample data below.
What I have is a row number which generated a number based on Date and Name columns (achieved using ROW_NUMBER function). What I need now, is another derived column called Group_Num which creates a number for each group (3 in this case). Can this be achieved considering the fact that my Name column repeats but the Date column value changes?
Thanks in advance.
Check This.
We can achive this using Row_number() ,lag() and SUM() .
select
Date,
Name,
Row_number()over( partition by Group_Num order by ROwiD ) Row_Num,
Group_Num
from
(
SELECT * ,
SUM(R) OVER(ORDER BY RowID) Group_Num
FROM
(
select *,
Case When
lag(name ) OVER (ORDER BY RowID ) = name
then 0 else 1 end as R
from
(
select DATE,NAME,
row_number() OVER ( ORDER BY (select 1)) AS 'RowID'
from #TableName
)A
)B
)C
order by ROwiD
OutPut :
You can use DENSE_RANK:
SELECT Date
, Name
, ROW_NUMBER() OVER(Partition By Name Order By Name, Date) as Row_Num
, DENSE_RANK() Over(order by Name) as Group_Num
FROM #Table