1. What is the difference between ROWNUM and FETCH FIRST N ROWS ONLY?
- ROWNUM is an older method used to limit the number of rows returned.
- It assigns a number to each row returned by a query, and you can use it to limit the number of rows.
- However, it is tricky to use with ORDER BY because ROWNUM is assigned before the sorting occurs.
- FETCH FIRST N ROWS ONLY is a more modern and intuitive SQL syntax introduced in Oracle 12c.
- It directly limits the result set to the top N rows after applying the ORDER BY clause, making it easier to use and more readable.
2. Can I use ROWNUM with ORDER BY directly?
- No, you cannot directly use ROWNUM with ORDER BY in a single query because ROWNUM is assigned before the ORDER BY is processed.
- To apply sorting with ROWNUM, you need to use a subquery, where the sorting happens first, followed by applying ROWNUM.
Example:
SELECT *
FROM (
SELECT * FROM employees ORDER BY salary DESC
)
WHERE ROWNUM <= 10;
3. How do I fetch rows starting from a specific point (pagination)?
- Starting with Oracle 12c, you can use the OFFSET and FETCH clauses to implement pagination.
- This allows you to skip a certain number of rows and then fetch the next N rows.
Example for pagination:
SELECT *
FROM employees
ORDER BY salary DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
- This will skip the first 20 rows and then fetch the next 10 rows.
4. What happens if two rows have the same value in the column I'm ordering by?
- If you use ROWNUM or FETCH FIRST N ROWS ONLY, Oracle will return rows based on the query’s sorting, but identical values may appear in any order unless a more specific method (like ROW_NUMBER() or DENSE_RANK()) is used to assign unique row numbers or ranks.
- DENSE_RANK() assigns the same rank to identical values but does not skip subsequent ranks, whereas ROW_NUMBER() assigns a unique number to each row, even if the values are identical.
5. Can I use ROWNUM in combination with DENSE_RANK() or ROW_NUMBER()?
- Yes, you can. In some cases, you may need to create an analytical query that ranks or numbers the rows in a result set using ROW_NUMBER() or DENSE_RANK() and then filter by that rank/row number in an outer query.
Example:
SELECT *
FROM (
SELECT employees.*, ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees
)
WHERE row_num <= 10;
6. How can I get the top N rows ordered by multiple columns?
- You can use the ORDER BY clause to order the rows by multiple columns. If you're using ROWNUM or FETCH, just list the columns in the ORDER BY clause.
Example:
SELECT *
FROM employees
ORDER BY department_id, salary DESC
FETCH FIRST 10 ROWS ONLY;
- This will return the top 10 employees, ordered first by department_id and then by salary in descending order.
7. What is the performance impact of using ROWNUM and FETCH FIRST N ROWS ONLY?
- FETCH FIRST N ROWS ONLY is generally more efficient and easier to use compared to ROWNUM, especially in Oracle 12c and later. It directly applies row limiting and sorting.
- ROWNUM may require subqueries for proper sorting and can be less efficient in such cases.
- When using ORDER BY, make sure to have proper indexes on the columns being ordered, as this will optimize the query's performance.
8. Can I get "Top N rows" for each group of rows (e.g., for each department or category)?
- Yes, you can use the ROW_NUMBER() or RANK() functions along with a PARTITION BY clause to get the top N rows for each group.
Example to get the top 3 highest-paid employees per department:
SELECT *
FROM (
SELECT employees.*, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num
FROM employees
)
WHERE row_num <= 3;
- This will return the top 3 employees for each department, ordered by salary.
9. What if I want the top N rows with ties?
- If you want to include ties in your results (e.g., two employees earning the same salary), use DENSE_RANK() or RANK() instead of ROW_NUMBER(). ROW_NUMBER() will always return unique row numbers, while DENSE_RANK() and RANK() will assign the same rank to identical values.
Example with DENSE_RANK():
SELECT *
FROM (
SELECT employees.*, DENSE_RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees
)
WHERE rank <= 10;
- This ensures that employees with the same salary will receive the same rank, and the query will return the top 10 employees with possible ties.
10. Can I use FETCH with pagination in Oracle versions before 12c?
- No, FETCH and OFFSET are only available in Oracle 12c and later. In earlier versions, you would need to use ROWNUM or a ROW_NUMBER() approach to handle pagination.
Example for pagination in older versions using ROW_NUMBER():
SELECT *
FROM (
SELECT employees.*, ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees
)
WHERE row_num BETWEEN 11 AND 20;
- This query fetches rows 11 to 20 based on salary ordering.
No comments:
Post a Comment