Generate a sequence number for every 3 rows in SQL - sql

I need to generate a sequence number for every three rows with some range. can this be done without iterations.
Example:
sequence
--------
1
1
1
2
2
2
3
3
3

Use this Analytic function
SELECT ( ( Row_number()OVER(ORDER BY order_by_column ) - 1 ) / 3 ) + 1 seq_no,
*
FROM tablename

Related

Row Number with specific window size

I want to group records by row numbers.
Like from row 1-3 in group 1 , 4-6 in group 2 , 7-9 in group 3 and so on.
Suppose below is the table structure:
Row NumberDataValue
1 A 10
2 A 5
3 A 1
4 A 33
5 A 2
6 A 127
1 B 1
2 B 0
3 B 7
4 B 7
5 B 5
6 B 8
7 B 1
8 B 0
I want a output like this:
GroupValue
1 10
1 5
1 1
2 33
2 2
2 127
1 1
1 0
1 7
2 7
2 5
2 8
3 1
3 0
I am using Oracle 11G.
I can achieve this using PL/SQL. But I have to use SQL only. As I have to use this query in a reporting tool.
If this is a duplicate question please provide the link of the answered question.
Subtract 1 from the column "RowNumber" and divide by 3.
Then use TRUNC() to get the integer part:
SELECT TRUNC(("RowNumber" - 1) / 3) + 1 "Group",
"Value"
FROM tablename
See the demo.
I would assume the name of the first column is ordering.
You can do:
select
1 + trunc(row_number() over(partition by data order by ordering) - 1) / 3,
value
from t
What you show looks like the output from something like this:
select ceil(rn/3) as grp, value
from your_table
order by rn;
Note that "row number" and "group" are reserved words/phrases which should not be used as column names. I used rn and grp instead.
I think the ceiling function is the simplest way to arrive at what you want. If you want to base it on the RowNumber column:
select ceil( RowNumber / 3.0) as grouping
If you want to calculate it yourself using row_number():
select ceil( row_number() over (order by RowNumber) / 3.0 ) as grouping

Select 4 rows at random with minimum values in sqlite

I have the following table:
addition
question answer box
1 + 1 2 0
1 + 2 3 2
1 + 3 4 1
1 + 4 5 2
1 + 5 6 3
1 + 6 7 1
I'm trying to select 4 rows with a minimum box value:
SELECT *, MIN(box) FROM {table} ORDER BY RANDOM() LIMIT 4;
However, it returns only one row.
Sounds like you want a cartesian product (CROSS JOIN) of two tables: the first table being what you presented above, and the second being the minimum value for column box.
Try this
SELECT * FROM {table}
CROSS JOIN
(SELECT MIN(box) from {table})
ORDER BY RANDOM() LIMIT 4;
Notice the subquery in the second half of the CROSS JOIN.

SQL: how to use row_number() function to assign the same number for rows with duplicate ids in a repeating format

I have a table with two columns personid and taskid and want to use the ROW_NUMBER function to add a row that counts up to 3 but will duplicate the number as it counts if there are multiple rows for a personid.
The code below is only ordering by personid and repeating after the number 3, but I need it to order by personid and only go to the next number after all the taskid's for the personid are assigned to one number, or essentially any duplicate personid's I want to make sure they all only get one number assigned to it.
Select
personid,
taskid,
1 + ( (row_number() over (order by personid) - 1) % 3) as numberCount
from taskTable
Current Table Being Queried From:
PersonId Taskid
1 1
1 2
1 6
2 3
3 8
3 10
4 9
4 4
4 5
5 7
5 11
5 12
Expected Results After Query:
PersonId Taskid numberCount
1 1 1
1 2 1
1 6 1
2 3 2
3 8 3
3 10 3
4 9 1
4 4 1
4 5 1
5 7 2
5 11 2
5 12 2
Try this below script using DENSE_RANK -
SELECT *,
(DENSE_RANK() OVER(ORDER BY PersonId)-1)%3 + 1 AS numberCount
FROM your_table
I think you want dense_rank() and modulo arithmetic:
select t.*,
(dense_rank() over (order by personId) - 1) % 3) + 1 as numberCount
from t;
Note: The syntax for modulo arithmetic may vary in your database. Typically it is one of mod(), the % operator, or using mod as an operator.

Replace a column value with random values

I want to replace values in a column with randomized values
NO LINE
-- ----
1 1
1 2
1 3
1 4
2 1
2 2
3 1
4 1
4 2
I want to randomize column NO and replace with random values. I have 5 million records and doing something like below script gives me 5 million unique NO's but as you can see NO is not unique and i want the same random value assigned for the same NO.
UPDATE table1
SET NO= abs(checksum(NewId())) % 100000000
I want my resultant dataset like below
NO LINE
------ ----
99 1
99 2
99 3
99 4
1092 1
1092 2
3456 1
41098 1
41098 2
I would recommend rand() with a seed:
UPDATE table1
SET NO = FLOOR(rand(NO) * 100000000);
This runs a slight risk of collisions, so two different NO rows could get the same value.
If the numbers do not need to be "random" you can give them consecutive values in an arbitrary order and avoid collisions:
with toupdate as (
select t1.*,
dense_rank() over (order by rand(NO), no) as new_no
from t
)
update toupdate
set no = new_no;

SQL Server GROUP BY COUNT Consecutive Rows Only

I have a table called DATA on Microsoft SQL Server 2008 R2 with three non-nullable integer fields: ID, Sequence, and Value. Sequence values with the same ID will be consecutive, but can start with any value. I need a query that will return a count of consecutive rows with the same ID and Value.
For example, let's say I have the following data:
ID Sequence Value
-- -------- -----
1 1 1
5 1 100
5 2 200
5 3 200
5 4 100
10 10 10
I want the following result:
ID Start Value Count
-- ----- ----- -----
1 1 1 1
5 1 100 1
5 2 200 2
5 4 100 1
10 10 10 1
I tried
SELECT ID, MIN([Sequence]) AS Start, Value, COUNT(*) AS [Count]
FROM DATA
GROUP BY ID, Value
ORDER BY ID, Start
but that gives
ID Start Value Count
-- ----- ----- -----
1 1 1 1
5 1 100 2
5 2 200 2
10 10 10 1
which groups all rows with the same values, not just consecutive rows.
Any ideas? From what I've seen, I believe I have to left join the table with itself on consecutive rows using ROW_NUMBER(), but I am not sure exactly how to get counts from that.
Thanks in advance.
You can use Sequence - ROW_NUMBER() OVER (ORDER BY ID, Val, Sequence) AS g to create a group:
SELECT
ID,
MIN(Sequence) AS Sequence,
Val,
COUNT(*) AS cnt
FROM
(
SELECT
ID,
Sequence,
Sequence - ROW_NUMBER() OVER (ORDER BY ID, Val, Sequence) AS g,
Val
FROM
yourtable
) AS s
GROUP BY
ID, Val, g
Please see a fiddle here.