Πώς μπορώ να περιορίσω τον αριθμό των σειρών που επιστρέφονται από ένα ερώτημα Oracle μετά την ταξινόμηση;

Υπάρχει τρόπος να κάνετε ένα ερώτημα Oracle να συμπεριφέρεται σαν να περιέχει μια ρήτρα MySQL limit;

Στην MySQL, μπορώ να το κάνω αυτό:

select * 
from sometable
order by name
limit 20,10

για να πάρω την 21η έως την 30η γραμμή (παραλείπω τις πρώτες 20, δίνω τις επόμενες 10). Οι σειρές επιλέγονται μετά την order by, οπότε ξεκινάει πραγματικά από το 20ο όνομα αλφαβητικά.

Στο Oracle, το μόνο πράγμα που αναφέρουν οι άνθρωποι είναι η ψευδοστήλη rownum, αλλά αξιολογείται πριν από την order by, πράγμα που σημαίνει το εξής:

select * 
from sometable
where rownum <= 10
order by name

θα επιστρέψει ένα τυχαίο σύνολο δέκα σειρών ταξινομημένων με βάση το όνομα, κάτι που συνήθως δεν είναι αυτό που θέλω. Επίσης, δεν επιτρέπει τον προσδιορισμό μιας μετατόπισης.

Μπορείτε να χρησιμοποιήσετε ένα υποερώτημα για αυτό, όπως


select *
from  
( select * 
  from emp 
  order by sal desc ) 
where ROWNUM 
Σχόλια (6)

Μια αναλυτική λύση με ένα μόνο ένθετο ερώτημα:

SELECT * FROM
(
   SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
) 
WHERE MyRow BETWEEN 10 AND 20;

Η Rank() θα μπορούσε να αντικαταστήσει την Row_Number() αλλά μπορεί να επιστρέψει περισσότερες εγγραφές από όσες περιμένετε αν υπάρχουν διπλές τιμές για το όνομα.

Σχόλια (3)

(μη δοκιμασμένο) κάτι σαν αυτό μπορεί να κάνει τη δουλειά

WITH
base AS
(
    select *                   -- get the table
    from sometable
    order by name              -- in the desired order
),
twenty AS
(
    select *                   -- get the first 30 rows
    from base
    where rownum < 30
    order by name              -- in the desired order
)
select *                       -- then get rows 21 .. 30
from twenty
where rownum > 20
order by name                  -- in the desired order

Υπάρχει επίσης η αναλυτική συνάρτηση rank, την οποία μπορείτε να χρησιμοποιήσετε για να διατάξετε κατά.

Σχόλια (2)