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

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

Related

SUM a column in SQL, based on DISTINCT values in another column, GROUP BY a third column

I'd appreciate some help on the following SQL problem:
I have a table of 3 columns:
ID Group Value
1 1 5
1 1 5
1 2 10
1 2 10
1 3 20
2 1 5
2 1 5
2 1 5
2 2 10
2 2 10
3 1 5
3 2 10
3 2 10
3 2 10
3 4 50
I need to group by ID, and I would like to SUM the values based on DISTINCT values in Group. So the value for a group is only accounted for once even though it may appear multiple for times for a particular ID.
So for IDs 1, 2 and 3, it should return 35, 15 and 65, respectively.
ID SUM
1 35
2 15
3 65
Note that each Group doesn't necessarily have a unique value
Thanks
the CTE will remove all duplicates, so if there a sdiffrenet values for ID and Group, it will be counted.
The next SELECT wil "GROUP By" ID
For Pstgres you would get
WITH CTE as
(SELECT DISTINCT "ID", "Group", "Value" FROM tablA
)
SELECT "ID", SUM("Value") FROM CTE GROUP BY "ID"
ORDER BY "ID"
ID | sum
-: | --:
1 | 35
2 | 15
3 | 65
db<>fiddle here
Given what we know at the moment this is what I'm thinking...
The CTE/Inline view eliminate duplicates before the sum occurs.
WITH CTE AS (SELECT DISTINCT ID, Group, Value FROM TableName)
SELECT ID, Sum(Value)
FROM CTE
GROUP BY ID
or
SELECT ID, Sum(Value)
FROM (SELECT DISTINCT * FROM TableName) CTE
GROUP BY ID

How to sum values in a column based on values in a different column SQL

For example, lets say I have
id
values
1
10
1
12
1
10
2
2
2
5
2
4
then i would want sql to return
id
values
1
32
2
11
This is very basic sql.
select id, sum(values) as values
from foo
group by id
Select ID,sum(values)
From table
Group by ID;

How do i select 4 rows from a table holding 10 rows of persons based on the youngest age?

Lets say i have a table containing these rows
id age
1 5
2 7
3 8
4 9
5 3
6 1
How do i write a select statement that selects exactly 4 of the youngest persons?
You would use top and order by:
select top (4) t.*
from t
order by age asc;
SELECT id, age
FROM [MyTable]
ORDER BY age
OFFSET 0 ROWS FETCH NEXT 4 ROWS ONLY

Get offset of a row after performing sort operation in 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

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;