Row number in sql having issue with generating - sql

I am facing one issue in below query
CREATE TABLE #tmp(rowid int,settle_id int)
insert into #tmp
select top 100
case when row_number() over (order by settle_id) > 10 then row_number() over (order by settle_id) - 10 else row_number() over (order by settle_id) end as rowid,settle_id from student_id(nolock)
select * from #tmp
drop table #tmp
I want row id should start from 1 -> 10 everytime but for first two sets it start from 1->10 but there after it starts with 11.
Please let me know what i am missing.

Use the below query to get the expected result.
SELECT
CASE WHEN ((row_number() over(order by settle_id) % 10) = 0)
THEN 10
ELSE (row_number() over (ORDER BY settle_id) % 10)
END AS RowID, settle_id
FROM student

Try using modulo arithmetic:
select ((row_number() over (order by settle_id) - 1) % 10) + 1 as rowid, settle_id
from student;
Some databases use the mod() function instead of %.

Related

Finding Median Using MySQL

I know that there are many ways to find the median, but I am trying to use this method to find the median. Can someone explain to me why this does not work? The error here says "Invalid use of group function," but when I use HAVING instead of WHERE, the system doesn't recognize what RowNumber is. I'm very confused.
SELECT
ROUND(AVG(LS.LAT_N))
FROM(
SELECT
LAT_N,
ROW_NUMBER() OVER (ORDER BY LAT_N) AS RowNumber
FROM
STATION
) AS LS
WHERE
RowNumber IN (
IF(
FLOOR(COUNT(LS.LAT_N)/2+0.5) = CEIL(COUNT(LS.LAT_N)/2+0.5),
FLOOR(COUNT(LS.LAT_N)/2+0.5),
FLOOR(COUNT(LS.LAT_N)/2+0.5) AND CEIL(COUNT(LS.LAT_N)/2+0.5)
)
I typically write this as:
SELECT AVG(LAT_N)
FROM (SELECT LAT_N,
ROW_NUMBER() OVER (ORDER BY LAT_N) AS RowNumber,
COUNT(*) OVER () as cnt
FROM STATION
) s
WHERE 2 * RowNumber IN (CNT, CNT + 1, CNT + 2);
Here is a db<>fiddle.
The median is the middle element in an ordered series - or the average of the two middle elements if there is an even number.
SELECT
AVG(LAT_N)
FROM(
SELECT
LAT_N,
ROW_NUMBER() OVER (ORDER BY LAT_N) AS RowNumber
FROM
STATION
) AS q
WHERE
RowNumber >= FLOOR ( (SELECT COUNT(*) FROM STATION)/2 + 0.5)
AND
RowNumber <= CEIL ( (SELECT COUNT(*) FROM STATION)/2 + 0.5)
Here is dbfiddle https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=b31e08f4ece61ecb95d9dde76c389fb1

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.

use the case statement and set a different value for every each top 10 records

I have a table that returns a list of records with two-column:
SELECT Id, Duration from dbo.[VW_ActivityDuration] ORDER BY DURATION desc
I want to use the case statement and set a different value for every top 10 records, which is ordered by DURATION in descending.
Example:
set the value as 5 for the first 10 records
and set the value as 4 for the next 10 records
and set the value as 3 for the other next 10 records
and set the value as 2 for the other next 10 records
similarly, I have to set the value of 1 for all after that
SELECT TOP (1000) [Id]
,[Name],
CASE
WHEN --- THEN '5'
ELSE '1'
END AS [Value]
FROM [EngagementDb].[dbo].[VW_ActivityDuration]
ORDER BY [DurationMinutes] desc
Any head-start, hints, or suggestions would be appreciated. I couldn't start writing a query to start with this problem.
I think you want row_number() and a case expression:
select id, DurationMinutes,
case
when row_number() over(order by DurationMinutes desc) <= 10 then 5
when row_number() over(order by DurationMinutes desc) <= 20 then 4
when row_number() over(order by DurationMinutes desc) <= 30 then 3
when row_number() over(order by DurationMinutes desc) <= 40 then 2
else 1
end as val
from [EngagementDb].[dbo].[VW_ActivityDuration]
order by DurationMinutes desc
We can shorten that a little with arithmetics:
select id, DurationMinutes,
case when row_number() over(order by DurationMinutes desc) <= 40
then 5 - (row_number() over(order by DurationMinutes desc) - 1) / 10
else 1
end as val
from [EngagementDb].[dbo].[VW_ActivityDuration]
order by DurationMinutes desc

How can I convert this select statement into an insert table in SQL Server?

I've found answers online, but none with specifically what I am doing. I couldn't get anything to work.
I have a select that randomly selects records and I just want to be able to have it insert into a table instead.
My SQL is
with data as (
select *, row_number() over (partition by DIVISION order by DIVISION) as rn
from WORK
)
select *
from data
where rn <= #randomNumber or (rn - #randomNumber) % 18 = 1 AND DIVISION != 4;
I know I am not supposed to do the partition by DIVISION order by DIVISION but that's a separate issue I believe.
I just need to be able to insert this data into another table WORK_CLEAN
You just need to add an insert statement.
with data as (
select *, row_number() over (partition by DIVISION order by DIVISION) as rn
from WORK
)
insert yourTable ([ColumnsHere])
select *
from data
where rn <= #randomNumber or (rn - #randomNumber) % 18 = 1 AND DIVISION != 4;

Select from table, if end is reached select from start in MSSQL

Is there any way to take a table and select 10 records from a start point but if the end of table is reached, go back to the start? So a table of 100 records, selecting 10 starting at record 95 would being 95-100 and 1-4.
Assuming that you have a column with the record number, then you can use arithmetic to define the ordering:
select t.*
from table t
order by (recnum + (100 - 95)) % 100) ;
If not:
select t.*
from table t cross join (select count(*) as cnt from t) x
order by (recnum + (x.cnt - 95)) % x.cnt) ;
If your records are not sequentially numbered, then you can add the number:
select t.*
from (select t.*, count(*) over () as cnt,
row_number() over (order by recnum) as seqnum
from table t
) t
order by (seqnum + (cnt - 95)) % cnt) ;