This question already has answers here:
How do I limit the number of rows returned by an Oracle query after ordering?
(14 answers)
Closed last year.
I'm having these schema
STUDENT (Sid, Name, City, Adm_date, Paper1, Paper2)
And I want to find the maximum number of students were admitted in which date and the city where maximum number of students lives.
I'm using these queries in ORACLE 11g Express Edition:
For City:
SELECT COUNT(Sid) AS No_of_students, City
FROM STUDENT
GROUP BY City
ORDER BY No_of_students DESC
LIMIT 1;
And For Date:
SELECT COUNT(Sid) AS No_of_students, Adm_date
FROM STUDENT
GROUP BY Adm_date
ORDER BY No_of_students DESC
LIMIT 1;
But here I'm getting error for both these tables:
ORA-00933: SQL command not properly ended
LIMIT is not part of Oracle's SQL dialect. In Oracle you would use the standard SQL FETCH FIRST clause instead, but in the old version you are using this is not available either.
And whatever approach you are following, keep in mind that there can be ties, i.e. more than one city or date with the maximum number of students. So LIMIT 1 would jump to short. FETCH FIRST does have a ties clause, but as mentioned, it is not available in your old Oracle version.
In Oracle 11g I'd use a window function to solve this:
SELECT city, no_of_students
FROM
(
SELECT
city,
COUNT(sid) AS no_of_students,
MAX(COUNT(sid)) OVER () AS max_no_of_students
FROM STUDENT
GROUP BY city
) counted
WHERE no_of_students = max_no_of_students;
Please try rownum with subquery (Since Limit is not available in Oracle):
For city wise:
select * from
(SELECT COUNT(Sid) AS No_of_students, City
FROM STUDENT
GROUP BY City
ORDER BY No_of_students DESC) where rownum=1
For Adm_date wise:
select * from
(SELECT COUNT(Sid) AS No_of_students, Adm_date
FROM STUDENT
GROUP BY Adm_date
ORDER BY No_of_students DESC) where rownum=1
Found a great article explaining the mechanism of selecting top-N rows using rownum:
https://blogs.oracle.com/oraclemagazine/post/on-rownum-and-limiting-results
Related
I'm a beginner to oracle. In recent search I've seen WHERE N-1,3-2 ..so on.
How does it work in searching data?
This is my code attemtp so far:
SELECT name, salary
FROM #Employee e1
WHERE N-1 = (SELECT COUNT(DISTINCT salary) FROM #Employee e2
WHERE e2.salary > e1.salary)
It's a classic( and pretty old ) SQL query to get nth highest salary. I assume It is no longer used( I haven't seen ) in any production codes, but could be a favourite question among the interviewers.
The N you are referring to is not a column or some unknown entity but a placeholder which should translate to a valid integer or bind argument in the working query. It is a correlated subquery, a subquery that is evaluated once for each row processed by the outer query. The way it works is that it takes a count of distinct list of salary values from employees that have a salary greater than each one of employees coming from the outer query and restricts the result where that count is equal to N-1.Which means you get those rows with nth highest salaries.
A more commonly used way to do this would be to use analytic function dense_rank() ( or rank depending on your need ). Read the documentation for these functions in case you aren't aware of them.
SELECT first_name,
salary
FROM (
SELECT e.*,
dense_rank() OVER(
ORDER BY salary desc
) rn
FROM employees e
)
WHERE rn = 6; -- ( n = 6 )
In Oracle 12c and higher versions, even though the above query works, a handy option to use is the FETCH..FIRST syntax.
SELECT *
FROM employees
ORDER BY salary DESC OFFSET 6 ROWS FETCH FIRST 1 ROWS WITH TIES; --n=6
This question already has answers here:
How do I limit the number of rows returned by an Oracle query after ordering?
(14 answers)
Closed 5 years ago.
What is wrong with below code?
SELECT first_name, last_name
FROM employees
UNION ALL
SELECT first_name, last_name
FROM dependents
ORDER BY last_name
LIMIT 6 OFFSET 1;
Even a simple query with LIMIT doesn't seem to be working :
SELECT first_name, last_name
FROM dependents
ORDER BY last_name
LIMIT 6 OFFSET 1;
Getting this error repeatedly: ORA-00933: SQL command not properly
ended
I believe oracle does not support LIMIT. Try this
ORDER BY last_name
OFFSET 1 ROWS FETCH NEXT 6 ROWS ONLY;
Note this syntax supports from Oracle 12c
What is wrong with the code is that Oracle does not support limit. Period. The most recent versions support the ANSI standard fetch first <n> rows only.
Perhaps you intend:
SELECT e.*
FROM (SELECT e.*, ROW_NUMBER() OVER (ORDER BY last_name) as seqnum
FROM (SELECT first_name, last_name FROM employees
UNION ALL
SELECT first_name, last_name
FROM dependents
) e
ORDER BY last_name
) e
WHERE seqnum BETWEEN 1 and 7;
I have to get second five (6-10) best salaries records from sorted table using ROWNUM.
Using ROWNUM is necessary.
When I execute query:
SELECT ROWNUM AS position, name, salary
FROM (SELECT name, salary
FROM employees
ORDER BY salary DESC)
WHERE ROWNUM <= 10;
I get a first 10 best records.
And now when I try execute query:
SELECT ROWNUM AS position, name, salary
FROM (SELECT name, salary
FROM employees
ORDER BY salary DESC)
WHERE ROWNUM >= 6 AND ROWNUM <= 10;
I get a empty table. Why doesn't it work?
As explained in the documentation, rownum is evaluated as the rows are fetched. If you never fetch the first row, you never get to the second. Hence, no rows are fetched:
Conditions testing for ROWNUM values greater than a positive integer
are always false. For example, this query returns no rows:
SELECT * FROM employees
WHERE ROWNUM > 1;
But, more importantly, you are using Oracle 12C. So, use fetch first instead of rownum. This has multiple advantages. Besides being standard SQL, you don't need a subquery:
SELECT name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 10 ROWS ONLY;
And for your second:
SELECT name, salary
FROM employees
ORDER BY salary DESC
OFFSET 5 ROWS
FETCH FIRST 5 ROWS ONLY;
I write in queston that using ROWNUM is necessary, because it's
academic task.
In such a case use a subquery
SELECT name, salary
FROM (
SELECT name, salary, ROWNUM as my_rownum
FROM employees
ORDER BY salary DESC
)
WHERE my_rownum BETWEEN 6 AND 10
You can use below query and try....
SELECT name,salary from
( SELECT name,salary, DENSE_RANK() OVER (ORDER BY salary DESC) as rn
from employees )
where rn between 6 and 10;
Does Presto SQL really lack TOP X functionality in SELECT statements?
If so, is there a workaround in the meantime?
https://prestodb.io/
If you simply want to limit the number of rows in the result set, you can use LIMIT, with or without ORDER BY:
SELECT department, salary
FROM employees
ORDER BY salary DESC
LIMIT 10
If you want the top values per group, you can use the standard SQL row_number() window function. For example, to get the top 3 employees per department by salary:
SELECT department, salary
FROM (
SELECT department, salary row_number() OVER (
PARTITION BY department
ORDER BY salary DESC) AS rn
FROM employees
)
WHERE rn <= 3
In oracle will the below query works for getting 3rd highest salary.
select empname, salary
from (select empname,salary from employee order by salary desc)
where rownum==3
I have seen answers in other threads but they seem to be complicated. If above query works then it is simple solution for oracle
What will be the query for SQLServer?
I don't have Oracle and SQLServer software to try out these queries.
Please let me know
For SQL server the solution would be like this:
Select TOP 1 Salary as '3rd Highest Salary'
from (SELECT DISTINCT TOP 3 Salary from Employee ORDER BY Salary DESC)
a ORDER BY Salary ASC
Use Dense_Rank() ranking function in SQL SERVER to find the 3rd highest salary.
Row_number() returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition.The ORDER BY clause determines the sequence in which the rows are assigned their unique ROW_NUMBER
SELECT empname,
salary
FROM (SELECT Dense_Rank() OVER(ORDER BY salary DESC) rn,
empname,
salary
FROM employee) A
WHERE rn = 3
I did some exploration and found below link which explains the difference between row_number(), rank() and dense_rank(). From the below link I found dense_rank() is suitable answer for this question.
http://www.dwbiconcepts.com/tutorial/24-interview-questions/190-top-20-sql-interview-questions-with-answers.html
row_number() does not give expected results if two or more empolyees has same salary.
Below query works for both Oracle and SQL Server when tried on http://sqlfiddle.com/. The following query gives you the list of employees with third highest salary
SELECT empname, salary FROM (SELECT empname, salary, dense_rank() over(order by salary desc) dense_rank_by_sal
FROM EMPLOYEE ) A where dense_rank_by_sal=3;