Using rownum with the combination of between keyword - oracle

I have seen this Oracle SQL query for using rownum with the combination of between keyword .
select *
from
( select rownum rnum, a.*
from (your_query) a
where rownum <= :M )
where rnum >= :N;
in order to get rows n through m from 'your query.'
I want to try it , Could anybody please tell me how can i get the data from an Emp table to fetch records from 4 to 8 Records
select *
from
( select rownum rnum, a.*
from (select * from emp) a
where rownum <= 4 )
where rnum >= 8;
But this isn't working , could anybody please tell me why .
Thank you very much .

This is because you are limiting your query to <=4 rows, so when you filter to show records >=8 there are only 4 records to look at....
Invert the numbers and you should see a result:
select *
from
( select rownum rnum, a.*
from (select * from emp) a
where rownum <= 8 )
where rnum >= 4;

If I had to guess, I'd say that the reason you're not seeing what you expect (in addition to having the operators backwards, as pointed out by #diagonalbatman) is that you didn't tell the database what order you wanted the rows in. You're essentially telling the database to return any 5 rows. You can't even be sure that this query will always return the same five rows. Any time you're getting a subset like this, you should use an order by clause in the innermost query, so that the sort is applied before the rownum values are issued:
SELECT *
FROM (SELECT ROWNUM rnum, a.*
FROM (SELECT *
FROM emp
ORDER BY emp_id) a
WHERE ROWNUM <= 8)
WHERE rnum >= 4;

When you are querying the whole data in the inner statement (if you have huge data amounds, no good idea!) you could as well use the BETWEEN keyword.
SELECT *
FROM
(SELECT rownum AS rnum,
a.*
FROM EMP) a
WHERE rnum BETWEEN 4 AND 8;

Related

ORA-00979 Not a Group function error for query with User defined function in select statement

I have this query where a user defined function is added in the select and group by statement.
The inner select query without the WITH clause runs fine and doesn't give any error. But after adding WITH clause it gives the following error -
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action: Error at Line: 3 Column: 29
I need the WITH clause to return only a subset of the entire result set based on input ranges.
Query is as follows:
WITH INFO AS (
SELECT
GET_EVAULATED_VALUE(T.C_IMP, T.IMP) AS IMPORTANCE,
count(*) AS NO_OF_PC_AFFECTED
FROM TABLE_NAME T
WHERE T.ACNT_REL_ID = 16
GROUP BY
(GET_EVAULATED_VALUE(T.C_IMP, T.IMP))
ORDER BY IMPORTANCE desc
)
SELECT * FROM
(
SELECT ROWNUM AS RN,
(SELECT COUNT(*) FROM INFO) COUNTS,
IMPORTANCE
FROM INFO
)
WHERE RN > 0 AND RN <= 10;
I am not sure how to use CTE with group by on user defined function. But I realized that I can rewrite the query to remove sub-query and CTE and make it simpler as following (and it works):
select * from (
select a.*, ROWNUM rnum from
(SELECT
count(*) over() as COUNTS,
GET_EVAULATED_VALUE(T.C_IMP, T.IMP) AS IMPORTANCE,
count(*) AS NO_OF_PC_AFFECTED
FROM TABLE_NAME T
WHERE T.ACNT_RELATION_ID = 16
GROUP BY
(GET_EVAULATED_VALUE(T.C_IMP, T.IMP))
ORDER BY importance desc) a
where ROWNUM <= 10 )
where rnum >= 0;
Same issue here, I created a table "TABLE_CTE" instead of using a CTE and it worked.
CREATE TABLE TABLE_CTE
AS
SELECT
USER_DEFINED_FUNCTION(date_1),
COUNT(*)
FROM
TABLE_NAME
GROUP BY
USER_DEFINED_FUNCTION(date_1)
;
SELECT * FROM TABLE_CTE

FROM keyword not found where expected while filtering data

I got one error
ORA-00923: FROM keyword not found where expected
Here is my query
SELECT * FROM
(SELECT *, (SELECT COUNT(*) FROM invoices) AS numberOfRows
FROM invoices ORDER BY Id DESC) WHERE rownum <= 1
I am begginer in Oracle SQL, but as I see here I have FROM keyword and it looks everythink OK.
I try to modify this query something like but still get another error
ORA-00933: SQL command not properly ended
SELECT * FROM
(SELECT COUNT(*) FROM invoices) AS numberOfRows
FROM invoices ORDER BY Id DESC) WHERE rownum <= 1
What is wrong in first select query ? What is missing ? Since I check everything, start from special character ( . , )
Also I try this kind of solution and get error
ORA-00936: missing expression
SELECT * FROM (SELECT , (SELECT COUNT() FROM invoices) AS numberOfRows FROM invoices ORDER BY Id DESC) WHERE rownum <= 1
The railroad diagram in the documentation:
... shows that you can either use * on its own, or <something>.* along with other columns or expressions. So you need to precede your * with the table name or an alias:
SELECT * FROM
(SELECT i.*, (SELECT COUNT(*) FROM invoices) AS numberOfRows
FROM invoices i ORDER BY Id DESC) WHERE rownum <= 1
If you're on a recent version of Oracle you can do this much more simply with:
select i.*, count(*) over () as numberOfRows
from invoices i
order by id desc
fetch first row only
On older version you still need a subquery, but only one level:
select *
from (
select i.*, count(*) over () as numberOfRows
from invoices i
order by id desc
)
where rownum = 1
db<>fiddle
looks like the FROM is missing from this select "SELECT *,"
SELECT * FROM
(SELECT , (SELECT COUNT() FROM invoices) AS numberOfRows
FROM invoices ORDER BY Id DESC) WHERE rownum <= 1

How can i avoid rownum as a column when limiting records in oracle?

when i run the query:
select *
from ( select a.*,
ROWNUM rnum
from ( select *
from test
order by null ) a
where ROWNUM <= 2000 )
where rnum >=1
I'm getting all the columns along with rownum as a separate column which I don't want, How to achieve this or is there any way to limit records?
Since the final filter is for ROWNUM >= 1 (which will always be true), you can eliminate that and just use:
select *
from (
select *
from test
order by null
)
where ROWNUM <= 2000
(Note: ORDER BY NULL will apply a non-deterministic ordering.)
If you want to specify a different starting row then you will need to specify the columns you want to return:
select col_1,
col_2,
-- ...
col_n
from (
select a.*,
ROWNUM rnum
from (
select *
from test
order by null
) a
where ROWNUM <= 2000
)
WHERE rnum > 1000
In Oracle 12c you can use:
SELECT *
FROM test
ORDER BY NULL
FETCH FIRST 2000 ROWS ONLY;
or
SELECT *
FROM test
ORDER BY NULL
OFFSET 1000 ROWS FETCH NEXT 1000 ROWS ONLY;

Row num is not working for duplicate columns while pagination

Code is written below, multiple nested query:
select *
from
(select employee_id,employee_id
from employees) a
where rownum <= 5
)
where rnum >= 10
If i give duplicate columns in the select its giving "column ambiguously defined" error.
employee_id,employee_id, rownum rnum
Firstly, your query is incorrect since you have ambiguously defined the columns. It will throw ORA-00918: column ambiguously defined.
You must use proper ALIAS to avoid the error. For example,
SELECT departments.department_id AS "dept_id",
employees.department_id AS "emp_Dept_id"
FROM...
Secondly, it is not at all a pagination query. Since you are alwyas going to pick random rows as there is no ORDER BY clause. You are not ordering the rows.
where rownum <= 5
where rnum >= 10
At last, how on earth could you try to fetch the rows beyond 10 when you have fetched ONLY 5 rows in the inner query? It will ALWAYS return zero rows.
The correct way of paging through data is:
SQL> SELECT empno
2 FROM (SELECT empno, rownum AS rnum
3 FROM (SELECT empno
4 FROM emp
5 ORDER BY sal)
6 WHERE rownum <= 8)
7 WHERE rnum >= 5;
EMPNO
----------
7654
7934
7844
7499
SQL>
when you give a.* it means you are trying to refer two columns with same name in a table which is not permitted.The column names in a table are unique
So select employee_id,employee_id from employees is not a problem
but
select a.* from (select employee_id,employee_id from employees)a is a problem
the sqlfiddle here
Also if you want records from 10 to 15 in your query then use like the below
select * from
(select a.*,Rownum rnum from
(select employee_id as emp_id1,employee_id as emp_id2
from employees order by 1)
a where rownum <= 15 ) where rnum >= 10
EDIT1:- If duplicate column is required use like the below
with emp1 as (select employee_id from employees),
emp2 as (select * from
(select a.*,rownum rnum from emp1 a order by 1)
where rownum <=15)
select b.*,c.*
from emp1 b,emp2 c
where b.employee_id=c.employee_id
and c.rnum >=10

Alternate of sql server TOP in oracle

How to get top 3 records in oracle pl sql?i am new to oracle,earlier i have used sql server.
My requirement is to get distinct top 3 records of Column X.
Try this to retrieve the Top N records from a query, you can use the following syntax::-
SELECT *
FROM (your ordered query) alias_name
WHERE rownum <= Rows_to_return
Example:-
SELECT *
FROM (select * from suppliers ORDER BY supplier_name) suppliers2
WHERE rownum <= 3
This may help you
SELECT ename, sal
FROM ( SELECT ename, sal, RANK() OVER (ORDER BY sal DESC) sal_rank
FROM emp )
WHERE sal_rank <= 3;

Resources