Get offset of a row after performing sort operation in sql - sql

I am using SQLite database.
Suppose I have rows with IDs 1 to 50. Then I perform select and order by operation.
Say, the result is IDs : 6,3,5,2,9,12,1,34,45,15.
Now, I want to know the offset of a particular row with given ID in the above result.e.g. offset of ID 1 is 6.
Can I do this in a single query?

put the query of ordered result into a subquery and use count(*) and check the id sequence:
Example:
SCHEMA:
CREATE TABLE tbl ("id" INTEGER,"val" INTEGER);
INSERT INTO tbl ("id","val")
VALUES
(12,6),(1,7),(34,8),(6,1),(9,5),
(45,9),(15,10),(3,2),(5,3),(2,4);
QUERY:
select id,(
select count(*)
from (
select id,val
from tbl order by val
) b
where a.val >= b.val)-1 as offset
from tbl a
order by offset
RESULT:
id offset
6 0
3 1
5 2
2 3
9 4
12 5
1 6
34 7
45 8
15 9
SQLFIDDLE DEMO

Related

offset does not work with Count(*) as order by

I have a query with Count(*) as order by with offset fetch next. When I am using different values as offset it is always providing the same resultset.
I tried with some column as order by where the resultset varies and it worked perfectly fine. Can someone help with this.
select
Id,
count(*) as "Count"
from
some_table
group by
"Id"
Order By
"Count" ASC OFFSET 0 ROWS FETCH NEXT 5 ROWS ONLY;
Screenshot 1
Screenshot 2
This is your query:
select Id, count(*) as "Count"
from some_table
group by "Id"
order by "Count" asc
OFFSET 0 ROWS FETCH NEXT 5 ROWS ONLY;
The problem is that you have duplicate values for count(*). Because SQL tables represent unordered sets, it has no default ordering. That poses a problem when sort keys have the same value.
The simple solution is to include id in the order by:
order by "Count" asc, id
This makes the sort stable, so it is well-defined.
here is the My example
Create a Table
create table t (id int, name varchar(100))
insert data's
insert into t values(1,'saravnan')
insert into t values(1,'kumar')
insert into t values(1,'Ravi')
insert into t values(1,'mohan')
insert into t values(2,'Raju')
insert into t values(2,'Vikram')
insert into t values(2,'AA')
insert into t values(2,'BB')
insert into t values(2,'CC')
insert into t values(2,'DD')
insert into t values(2,'EE')
insert into t values(3,'Raju')
insert into t values(3,'Vikram')
insert into t values(3,'AA')
insert into t values(4,'BB')
insert into t values(4,'CC')
insert into t values(4,'DD')
insert into t values(4,'EE')
select all data
select *from t
id name
1 1 saravnan
2 1 kumar
3 1 Ravi
4 1 mohan
5 2 Raju
6 2 Vikram
7 2 AA
8 2 BB
9 2 CC
10 2 DD
11 2 EE
12 3 Raju
13 3 Vikram
14 3 AA
15 4 BB
16 4 CC
17 4 DD
18 4 EE
offset is used for Number of rows skip from start of the table data. it should be number.
here my example:
select id,count(*) from t group by id order by id offset 1 rows fetch next 3 row only
It returns
id count
1 2 7
2 3 3
3 4 4
The fetch next used for number rows to return.
Solution for your example .
--offset 0 returns[enter image description here][1]
select Id,count(1) as "Count" from t group by ID Order By "Count" ASC OFFSET 0 ROWS FETCH NEXT 5 ROWS ONLY
Id Count
1 3 3
2 4 4
3 1 4
4 2 7
-- offset 1 returns
select Id,count(1) as "Count" from t group by ID Order By "Count" ASC OFFSET 1 ROWS FETCH NEXT 5 ROWS ONLY
Id Count
1 4 4
2 1 4
3 2 7

Get ID of row from max value

I'm new in database
I have the following table:
id group factor
------------------------
1 11 1
2 11 5
4 11 2
5 12 3
6 12 2
7 13 4
8 13 1
9 13 8
10 14 6
I need to get the id of the one that has the largest factor based on its group, for example, in the case of group 11, the row with the largest factor is 5, so I need to obtain the id of that row, in this case 2.
please if someone can show me the right way.
You could use:
SELECT DISTINCT ON(group) group factor, id
FROM tab
ORDER BY group, factor DESC;
db<>fiddle demo
You can use simple CTE (Common Table Expression) for it, as in:
with
x as (
select group_id, max(factor) as max_factor from my_table group by group_id
)
select t.*
from my_table t
join x on x.group_id = t.group_id and x.max_factor = t.factor
This solution has the [desirable?] feature that in case there are multiple rows tied in first place in the same group, it will show them all, not just one [randomly] of them.
If you know the group in advance, e.g. 11, then you can simply do:
SELECT id
FROM tab
WHERE group = 11
ORDER BY factor DESC
LIMIT 1;
Otherwise if you want the result for each group that exists in the table then Lukasz Szozda's answer it the way to go.

SQL - Add value with previous row only

I have a table named myvals with the following fields:
ID number
-- -------
1 7
2 3
3 4
4 0
5 9
Starting on 2nd row, I would like to add the number with the previous row number. So, my end result would look like this
ID number
-- ------
1 7
2 10
3 7
4 4
5 9
You could use the LAG analytic function
SELECT Id, number + LAG(number,1,0) OVER (ORDER BY Id) FROM table
First thing's first. You can't add to null to ID 1 must have a value.
create table #temp
(
month_type datetime,
value int
)
insert into #temp
Select '2015/01/01',1
union
Select '2015/02/01',2
union
Select '2015/03/01',3
union
Select '2015/04/01',4
SELECT t.value,t1.value,(t.value+t1.value)/2 FROM #temp t1
left join #temp t on t.month_type=Dateadd(MONTH,-1,t1.month_type)

Select all items with sum of fields in specified range

I have simple table:
file_size file_id file_time
1 1 19
2 2 20
3 3 21
4 4 22
5 5 23
I want to find such item that all items with less file_time has the sum of file_size in predefined range.
I written next query:
SELECT * FROM test_table AS D0 WHERE
(SELECT TOTAL(file_size) FROM test_table AS D1 WHERE
D1.file_time <= D0.file_time ORDER BY file_id)
BETWEEN 1 AND 9
This query get correct results:
1 1 19
2 2 20
3 3 21
But this query does not work if needed items has the same file_time field:
file_size file_id file_time
1 1 20
2 2 20
3 3 20
4 4 20
5 5 20
The desired result for this data is:
1 1 20
2 2 20
3 3 20
The file_id field is unique.
What is wrong in my SQL-query?
The code to create test table:
CREATE TABLE test_table (file_size INT, file_id INT, file_time INT)
INSERT INTO test_table VALUES(1,1,20)
INSERT INTO test_table VALUES(2,2,20)
INSERT INTO test_table VALUES(3,3,20)
INSERT INTO test_table VALUES(4,4,20)
INSERT INTO test_table VALUES(5,5,20)
You shouldn't consider file_time as a single column in your query, since you want to consider the column file_id either. You should use the pairs of file_time and file_id and you should compare them lexicographically as follows:
SELECT *
FROM test_table AS D0
WHERE (
SELECT TOTAL( file_size )
FROM test_table AS D1
WHERE D1.file_time < D0.file_time
OR (
D1.file_time = D0.file_time
AND D1.file_id <= D0.file_id
)
ORDER BY file_time, file_id DESC
)
BETWEEN 1
AND 9
Not sure if I understood but I think
-- sum of file sizes between 1 and 7 with the lowest time
SELECT SUM(test.file_size) AS sum_file_size, test.file_time
FROM test
WHERE (test.file_time = (SELECT TOP 1 test.file_time
FROM test
ORDER BY file_time))
AND (test.file_size BETWEEN 1 AND 9)
GROUP BY test.file_time;
-- sum of file sizes per time `group`
SELECT SUM(test.file_size) AS sum_file_size, test.file_time,
FROM test
WHERE (test.file_size BETWEEN 1 AND 7)
GROUP BY test.file_time
ORDER BY test.file_time;

How to ignore certain similar rows when select

I have the following table
Id col1 col2 col3
1 c 2 m
2 c 3 6
2 b d u
3 e 6 9
4 1 v 8
4 2 b t
4 4 5 g
As you can see, there are duplicate value in id column, 2 and 4. I only want to select rows with unique id value and ignore the following rows with duplicate id value. I just want to keep the first of the rows with duplicate values
1 c 2 m
2 c 3 6
3 e 6 9
4 1 v 8
There is FK constraint, so I cannot delete rows with duplicate values.
I am using SQL SERVER 2008 R2
Any reply will be appreciated.
You can use row_number to number each row with the same id. Then you can select only the first row per id:
select *
from (
select row_number() over (partition by id order by col1, col2, col3) rn
from YourTable
) as SubQueryAlias
where rn = 1
The subquery is required because SQL Server doesn't allow row_number directly in the where clause.