Sipariş verdikten sonra bir Oracle sorgusu tarafından döndürülen satır sayısını nasıl sınırlayabilirim?


1032

Bir Oraclesorgunun bir MySQL limityan tümce içeriyormuş gibi davranmasının bir yolu var mı ?

İçinde MySQLbunu yapabilirim:

select * 
from sometable
order by name
limit 20,10

21. sırayı 30. sıraya çıkarmak için (ilk 20'yi atlayın, sonraki 10'u verin). Satırlar 'dan sonra seçilir order by, bu yüzden gerçekten 20. isimde alfabetik olarak başlar.

In Oracle, insanların bahsettiği tek şey rownumsözde sütun, ancak daha önce değerlendirilir order by, bu şu anlama gelir:

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

genellikle istediğim gibi olmayan, sıraya göre sıralı on satırlık rastgele bir set döndürür. Ayrıca bir ofset belirtilmesine izin vermez.


16
SQL'de standardize edilmiştir: 2008.
dalle

14
Tom Kyte tarafından Oracle 12c için limit açıklandı ...
wolφi

14
Sonuç kümesindeki sonraki sayfa getiriliyor mu?
Mathieu Longtin

3
@YaroslavShabalin Özellikle sayfalı bir arama bu kalıbı her zaman kullanır . Herhangi bir arama fonksiyonu ile hemen hemen her uygulama onu kullanacak. Başka bir kullanım durumu, uzun bir listenin veya tablo istemcisi tarafının yalnızca bir kısmını yüklemek ve kullanıcıya genişleme seçeneği sunmaktır.
jpmc26

3
@YaroslavShabalin Temel veriler değişmediği sürece farklı bir sonuç kümesi alamazsınız ORDER BY. Önce sipariş vermenin bütün mesele bu. Temel veriler değişirse ve sonuç kümeniz bu nedenle değişirse, neden kullanıcıya güncel olmayan bilgiler yerine güncellenmiş sonuçları göstermiyorsunuz? Ayrıca, devlet yönetimi mümkün olduğunca kaçınılması gereken bir vebadır. Sürekli bir komplikasyon ve böcek kaynağıdır; işte bu yüzden fonksiyonel hale geliyor. Ve ne zaman hafızadaki tüm sonucun ne zaman sona ereceğini bilirsiniz? Web'de, kullanıcının ne zaman ayrıldığını bilmenin bir yolu yoktur.
jpmc26

Yanıtlar:


620

Oracle 12c R1 (12.1) başlanarak, orada olduğu bir madde sınırlayıcı satır . Tanıdık LIMITsözdizimini kullanmaz , ancak daha fazla seçenekle işi daha iyi yapabilir. Sözdiziminin tamamını burada bulabilirsiniz . ( Bu yanıtta bunun Oracle'da dahili olarak nasıl çalıştığı hakkında daha fazla bilgi edinin ).

Orijinal soruyu cevaplamak için sorgu:

SELECT * 
FROM   sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

(Önceki Oracle sürümleri için lütfen bu sorudaki diğer yanıtlara bakın)


Örnekler:

Aşağıdaki örnekler, bağlantı çürümesini önleme umuduyla bağlantılı sayfadan alıntılanmıştır .

Kurmak

CREATE TABLE rownum_order_test (
  val  NUMBER
);

INSERT ALL
  INTO rownum_order_test
SELECT level
FROM   dual
CONNECT BY level <= 10;

COMMIT;

Tabloda ne var?

SELECT val
FROM   rownum_order_test
ORDER BY val;

       VAL
----------
         1
         1
         2
         2
         3
         3
         4
         4
         5
         5
         6
         6
         7
         7
         8
         8
         9
         9
        10
        10

20 rows selected.

İlk Nsatırları alın

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;

       VAL
----------
        10
        10
         9
         9
         8

5 rows selected.

İlk alın Neğer satırları Ninci satır bağları var, hepsi bağlı satırları almak

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS WITH TIES;

       VAL
----------
        10
        10
         9
         9
         8
         8

6 rows selected.

xSatırların en üst % 'si

SELECT val
FROM   rownum_order_test
ORDER BY val
FETCH FIRST 20 PERCENT ROWS ONLY;

       VAL
----------
         1
         1
         2
         2

4 rows selected.

Ofset kullanma, sayfalandırma için çok yararlı

SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

Ofseti yüzdelerle birleştirebilirsiniz

SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 20 PERCENT ROWS ONLY;

       VAL
----------
         3
         3
         4
         4

4 rows selected.


1
Sadece uzatmak için: OFFSET FETCHsözdizimi bir sözdizimi şekeri. Ayrıntılar
Lukasz Szozda

793

Bunun için bir alt sorgu kullanabilirsiniz

select *
from  
( select * 
  from emp 
  order by sal desc ) 
where ROWNUM <= 5;

Daha fazla bilgi için ROWNUM hakkında ve Oracle / AskTom'daki sonuçları sınırlama konusuna da göz atın .

Güncelleme : Hem alt hem de üst sınırlarla sonucu sınırlamak için işler biraz daha şişirilir

select * from 
( select a.*, ROWNUM rnum from 
  ( <your_query_goes_here, with order by> ) a 
  where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum  >= :MIN_ROW_TO_FETCH;

(Belirtilen AskTom makalesinden kopyalandı)

Güncelleme 2 : Oracle 12c (12.1) ile başlayarak satırları sınırlamak veya ofsetlerden başlamak için bir sözdizimi vardır.

SELECT * 
FROM   sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

Daha fazla örnek için bu cevaba bakınız . İpucu için Krumia'ya teşekkürler.


5
Bu kesinlikle bunu yapmanın bir yoludur, ancak en fazla rownum arttıkça sorgu performansının düştüğünü unutmayın. Bu, yalnızca ilk birkaç sayfayı görmek istediğiniz sorgu sonuçları için iyi bir çözümdür, ancak bunu tüm tablo boyunca sayfa kodlama mekanizması olarak kullanıyorsanız, kodunuzu yeniden düzenlemekten daha iyi olur
Chris Gill

1
+1 alt / üst sürümünüz aslında üst sınır rownum yan tümcesinin sorgumu önemli ölçüde yavaşlattığı bir soruna geçici bir çözüm bulmama yardımcı oldu.
Kelvin

1
Leigh Riffel “sadece bir iç içe sorgu ile analitik çözüm”.
Darren Hicks

7
AskTom makalesinde SELECT / * + FIRST_ROWS (n) / a kullanan bir iyileştirici ipucu da vardır . , rownum rnum Kapatılan eğik çizgiden önce bir yıldız işareti gelmelidir. SO temizliyor.
David Mann

1
Oracle 11 için ROWNUM'a sahip bir dış SEÇİM'in bir UpdatableResultSet (ORA-01446 ile) üzerinde deleteRow'u çağırmanızı engelleyeceğini unutmayın - bu 12c R1 değişikliğini dört gözle bekleyin!
nsandersen

185

Aşağıdaki yaklaşımlar için bazı performans testleri yaptım:

Asktom

select * from (
  select a.*, ROWNUM rnum from (
    <select statement with order by clause>
  ) a where rownum <= MAX_ROW
) where rnum >= MIN_ROW

Analitik

select * from (
  <select statement with order by clause>
) where myrow between MIN_ROW and MAX_ROW

Kısa Alternatif

select * from (
  select statement, rownum as RN with order by clause
) where a.rn >= MIN_ROW and a.rn <= MAX_ROW

Sonuçlar

Tabloda 10 milyon kayıt vardı, sıralaması dizine eklenmemiş bir tarih saatindeydi:

  • Açıklama planı her üç seçim için de aynı değeri gösterdi (323168)
  • Ama kazanan AskTom (analitik takip eden)

İlk 10 satırı seçmek:

  • AskTom: 28-30 saniye
  • Analitik: 33-37 saniye
  • Kısa alternatif: 110-140 saniye

100.000 ve 100.010 arasındaki satırları seçme:

  • AskTom: 60 saniye
  • Analitik: 100 saniye

9.000.000 ve 9.000.010 arasındaki satırları seçme:

  • AskTom: 130 saniye
  • Analitik: 150 saniye

İyi iş. > = Ve <= yerine kısa alternatifi denediniz mi?
Mathieu Longtin

4
@MathieuLongtin BETWEENsadece bir kısayol >= AND <=( stackoverflow.com/questions/4809083/between-clause-versus-and )
wweicker

1
zeldi - Bu hangi versiyondaydı? Oracle, 11.1'de analitik performans iyileştirmeleri yaptı. ve 11.2.
Leigh Riffel

@Righ Riffel 10.2.0.5 idi; bir gün zaman alabilir ve ayrıca 11i sürümünü kontrol edebilirim.
zeldi

5
Bazı hızlı testler yaptım ve 12c için benzer sonuçlar aldım. Yeni offsetsözdizimi, analitik yaklaşımla aynı plana ve performansa sahiptir.
Jon Heller

55

Yalnızca bir iç içe sorgu içeren analitik bir çözüm:

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

Rank()yerine ikame edilebilir, Row_Number()ancak ad için yinelenen değerler olup olmadığını beklediğinizden daha fazla kayıt döndürebilir.


3
Analitiği seviyorum. Rank () ve Row_Number () arasındaki davranış farkının ne olacağını açıklığa kavuşturmak isteyebilirsiniz.
Dave Costa

Gerçekten, kopyaları neden düşünmediğimden emin değilim. Bu nedenle, ad için yinelenen değerler varsa, RANK beklediğinizden daha fazla kayıt verebilir, bu nedenle Row_Number kullanmanız gerekir.
Leigh Riffel

Eğer belirtmek gerekirse, ikincisi sayıları "atlamıyor" iken çıkış kontrolü için hangisinin daha yararlı olabileceğini belirtmek rank()gerekir . Her durumda bu soru için en uygunudur. Bir diğer değil, bu teknik belirtilen işlevleri destekleyen herhangi bir db için uygulanabilir olmasıdır. dense_rank()rank()row_number()
Used_By_Already

28

Oracle 12c'de ( SQL başvurusunda satır sınırlama maddesine bakın ):

SELECT * 
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

53
Ve elbette, şimdiye kadar herkesten tamamen farklı bir sözdizimi kullanmak zorunda kaldılar
Mathieu Longtin

9
LIMITSQL: 2008'de anlaşmaya varmak için diğer tüm satıcılarla birlikte oturduktan sonra, Microsoft'un kitabından bir yaprak almak ve standardı kırmak zorunda kaldılar.
beldaz

1
İlginç bir şekilde, en son standardın bu sözdizimini içerdiğini duydum, belki Oracle uygulamadan önce ilk kez itti. Tartışmasız daha esnekLIMIT ... OFFSET
beldaz

3
@Derek: Evet, standarda uymamak üzücü. Ancak 12cR1'de yeni tanıtılan işlevsellik sadece daha güçlüdür LIMIT n, m(Cevabımı görün). Sonra tekrar, Oracle'ın LIMIT n, meşdeğer olduğu gibi sözdizimsel şeker olarak uygulanması gerekirdi OFFSET n ROWS FETCH NEXT m ROWS ONLY.
sampathsris

10
@Derek: Aslında, bu açıklamayı PostgreSQL kılavuzunda gördüm postgresql.org/docs/9.0/static/sql-select.html#AEN69535 " MySQL tarafından kullanılan postgresql.org/docs/9.0/static/sql-select.html#AEN69535 " cümleleri PostgreSQL'e özel sözdizimi olduğunu . : 2008 standardı aynı işlevsellik için OFFSET ... FETCH {FIRST | NEXT} ... maddelerini tanıttı ". Bu yüzden LIMIT asla standardın bir parçası değildi.
beldaz

14

Oracle'da sipariş içeren sayfalama sorguları gerçekten zor.

Oracle, veritabanının satırı tablodan veya birleştirilmiş görünümler kümesinden seçme sırasını gösteren bir sayı döndüren bir ROWNUM sözde sütunu sağlar.

ROWNUM, birçok insanın başını belaya sokan bir sahte sütundur. Bir ROWNUM değeri bir satıra kalıcı olarak atanmaz (bu yaygın bir yanlış anlamadır). Bir ROWNUM değeri gerçekten atandığında kafa karıştırıcı olabilir. Bir ROWNUM değeri, sorgunun filtre tahminlerini geçtikten sonra , ancak sorgu toplama veya sıralamadan önce bir satıra atanır .

Dahası, bir ROWNUM değeri ancak atandıktan sonra artırılır.

Bu nedenle, aşağıdaki sorgu hiçbir satır döndürmez:

 select * 
 from (select *
       from some_table
       order by some_column)
 where ROWNUM <= 4 and ROWNUM > 1; 

Sorgu sonucunun ilk satırı ROWNUM> 1 yüklemini geçmez, bu nedenle ROWNUM 2'ye artmaz. Bu nedenle, hiçbir ROWNUM değeri 1'den büyük olmaz, sonuç olarak sorgu hiçbir satır döndürmez.

Doğru şekilde tanımlanmış sorgu şöyle görünmelidir:

select *
from (select *, ROWNUM rnum
      from (select *
            from skijump_results
            order by points)
      where ROWNUM <= 4)
where rnum > 1; 

Vertabelo blogundaki makalelerimde sayfalandırma sorguları hakkında daha fazla bilgi edinin :


2
Sorgu sonucunun ilk satırı ROWNUM> 1 predicate (…) 'i geçmez - bunu açıklamak için oy verin.
Piotr Dobrogost

6

SQL Standardı

Bu makalede açıkladığım gibi , SQL: 2008 Standardı SQL sonuç kümesini sınırlamak için aşağıdaki sözdizimini sağlar:

SELECT
    title
FROM
    post
ORDER BY
    id DESC
FETCH FIRST 50 ROWS ONLY

Oracle 11g ve daha eski sürümleri

Sürüm 12c'den önce Top-N kayıtlarını almak için türetilmiş bir tablo ve ROWNUM sözde sütunu kullanmanız gerekiyordu:

SELECT *
FROM (
    SELECT
        title
    FROM
        post
    ORDER BY
        id DESC
)
WHERE ROWNUM <= 50

5

Daha az SELECT ifadesi. Ayrıca, daha az performans tüketir. Kredi: anibal@upf.br

SELECT *
    FROM   (SELECT t.*,
                   rownum AS rn
            FROM   shhospede t) a
    WHERE  a.rn >= in_first
    AND    a.rn <= in_first;

2
Ayrıca, bu tamamen yanlış bir cevaptır. Soru sıralamadan SONRA sınırlamakla ilgiliydi. Yani rownum alt sorgudan çıkmış olmalı.
BitLord

5

Kabul edilen cevabın bir uzantısı olarak Oracle dahili olarak ROW_NUMBER/RANKfonksiyonları kullanır . OFFSET FETCHsözdizimi bir sözdizimi şekeri.

DBMS_UTILITY.EXPAND_SQL_TEXTProsedür kullanılarak gözlemlenebilir :

Numune hazırlanıyor:

CREATE TABLE rownum_order_test (
  val  NUMBER
);

INSERT ALL
  INTO rownum_order_test
SELECT level
FROM   dual
CONNECT BY level <= 10;
COMMIT;

Sorgu:

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;

düzenli:

SELECT "A1"."VAL" "VAL" 
FROM  (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
               ROW_NUMBER() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rownumber" 
      FROM "ROWNUM_ORDER_TEST" "A2") "A1" 
WHERE "A1"."rowlimit_$$_rownumber"<=5 ORDER BY "A1"."rowlimit_$_0" DESC;

db <> keman demosu

Genişletilmiş SQL metni getiriliyor:

declare
  x VARCHAR2(1000);
begin
 dbms_utility.expand_sql_text(
        input_sql_text => '
          SELECT val
          FROM   rownum_order_test
          ORDER BY val DESC
          FETCH FIRST 5 ROWS ONLY',
        output_sql_text => x);

  dbms_output.put_line(x);
end;
/

WITH TIESşu şekilde genişletilir RANK:

declare
  x VARCHAR2(1000);
begin
 dbms_utility.expand_sql_text(
        input_sql_text => '
          SELECT val
          FROM   rownum_order_test
          ORDER BY val DESC
          FETCH FIRST 5 ROWS WITH TIES',
        output_sql_text => x);

  dbms_output.put_line(x);
end;
/

SELECT "A1"."VAL" "VAL" 
FROM  (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
              RANK() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rank" 
       FROM "ROWNUM_ORDER_TEST" "A2") "A1" 
WHERE "A1"."rowlimit_$$_rank"<=5 ORDER BY "A1"."rowlimit_$_0" DESC

ve ofset:

declare
  x VARCHAR2(1000);
begin
 dbms_utility.expand_sql_text(
        input_sql_text => '
          SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY',
        output_sql_text => x);

  dbms_output.put_line(x);
end;
/


SELECT "A1"."VAL" "VAL" 
FROM  (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
             ROW_NUMBER() OVER ( ORDER BY "A2"."VAL") "rowlimit_$$_rownumber" 
       FROM "ROWNUM_ORDER_TEST" "A2") "A1" 
       WHERE "A1"."rowlimit_$$_rownumber"<=CASE  WHEN (4>=0) THEN FLOOR(TO_NUMBER(4)) 
             ELSE 0 END +4 AND "A1"."rowlimit_$$_rownumber">4 
ORDER BY "A1"."rowlimit_$_0"

3

Oracle 12C'de değilseniz, aşağıdaki gibi TOP N sorgusunu kullanabilirsiniz.

SELECT *
 FROM
   ( SELECT rownum rnum
          , a.*
       FROM sometable a 
   ORDER BY name
   )
WHERE rnum BETWEEN 10 AND 20;

Hatta bu maddeyi aşağıdaki maddeden de taşıyabilirsiniz.

WITH b AS
( SELECT rownum rnum
      , a.* 
   FROM sometable a ORDER BY name
) 
SELECT * FROM b 
WHERE rnum BETWEEN 10 AND 20;

Burada aslında satır içi bir görünüm oluşturuyoruz ve rownum'u rnum olarak yeniden adlandırıyoruz. Ana sorgudaki rnum'u filtre ölçütü olarak kullanabilirsiniz.


1
Benim durumumda bu doğru satırları döndürmedi. Bunu düzeltmek için yaptığım ORDER BYve rownumayrı ayrı yapmaktır . Temelde ORDER BYyan tümcesi olan bir alt sorgu oluşturdum .
Patrick Gregorio

Yanlış cevap olduğu için aşağı oy. Soru, rownumbir alt sorgunun dışında olması gereken sıralamadan sonra sınırlama ile ilgilidir .
Piotr Dobrogost

@PiotrDobrogost rownum sadece dışarıda.
sandi

2

Ben 12c karşı doğrulanmış Oracle 1z0-047 sınava hazırlanmaya başladım Bunun için hazırlanırken ben 'FETCH FIRST' olarak bilinen bir 12c geliştirme rastladım Size kolaylık göre satır / sınır satır getirmenizi sağlar. Bununla birlikte çeşitli seçenekler mevcuttur

- FETCH FIRST n ROWS ONLY
 - OFFSET n ROWS FETCH NEXT N1 ROWS ONLY // leave the n rows and display next N1 rows
 - n % rows via FETCH FIRST N PERCENT ROWS ONLY

Misal:

Select * from XYZ a
order by a.pqr
FETCH FIRST 10 ROWS ONLY

3
stackoverflow.com/a/26051830/635608 - bu, diğer yanıtlarda zaten sağlanmıştır. Lütfen aylar önce gönderilmiş olan şeyleri göndermekten kaçının.
Mat

1
Ah eminim, her cevaptan geçmedim, alt sorgulara erken rastladım, bunu akılda tutacağım.
arjun gaur

1
select * FROM (SELECT 
   ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
 FROM EMP ) EMP  where ROWID=5

değerler daha büyük

select * FROM (SELECT 
       ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
     FROM EMP ) EMP  where ROWID>5

değerler daha az

select * FROM (SELECT 
       ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
     FROM EMP ) EMP  where ROWID=5

Temel ROW_NUMBER()çözüm olarak downvote zaten Leigh Riffel tarafından gönderilmişti. Bağımlılıkta gösterilen kodda sözdizimi hataları var.
Piotr Dobrogost

1

Bir sorgu tarafından döndürülen her satır için, ROWNUM sözde sütunu, Oracle'ın satırı tablodan veya birleştirilmiş satırlar kümesinden seçme sırasını gösteren bir sayı döndürür. Seçilen ilk satırın ROWNUM değeri 1, ikincisi 2, vb.

  SELECT * FROM sometable1 so
    WHERE so.id IN (
    SELECT so2.id from sometable2 so2
    WHERE ROWNUM <=5
    )
    AND ORDER BY so.somefield AND ROWNUM <= 100 

Bunu oraclesunucuda uyguladım11.2.0.1.0


soru sıralı satırları sınırlama sorusunu sorduğunda ve siparişiniz bile yoksa
Piotr Dobrogost 13:19

@PiotrDobrogost Büyük bir görev olmadığını anlayın, anahtar kelimelerin sıralanması tüm rdbms için ortak olan sadece limit değişiklikleri var.
Sumesh TG

-1

SQL-Developer durumunda, yalnızca ilk 50 satırı otomatik olarak getirir. Ve eğer aşağı kaydırırsak, 50 satır daha getirir!

Bu nedenle, sql-geliştirici aracı durumunda tanımlamamız gerekmiyor!


-3

Kehanette

SELECT val FROM   rownum_order_test ORDER BY val DESC FETCH FIRST 5 ROWS ONLY;

VAL

    10
    10
     9
     9
     8

5 satır seçildi.

SQL>


7
Bunun Oracle 12c'den başlayarak geçerli olduğunu ve bunu bir yerden kopyaladığınızı / yapıştırdığınızı belirtmelisiniz - lütfen kaynaklarınızı her zaman belirtin.
Mat

Kaynak bu @Mat. Rakesh, lütfen en azından orijinal sorunun cevabını uyarlamayı deneyin. Aynı kaynağı alıntılayan bir cevap da verdim, ancak kapsamlı olmaya çalıştım ve orijinal kaynaktan alıntı yaptım.
sampathsris

-4

(denenmemiş) böyle bir şey işi yapabilir

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

Ayrıca, sipariş vermek için kullanabileceğiniz analitik fonksiyon sırası da vardır.


2
ROWNUM sonuç kümesindeki bir sütun olduğundan, son WHERE koşulunun her zaman yanlış olacağı için bu, tek bir satır döndürmez. Ayrıca, ROWNUM ve ORDER BY bir garanti ORDER kullanamazsınız.
Ben

2
Mükemmel. Bunu başkalarına bir uyarı olarak burada bırakalım.
EvilTeach

-5

Düzeltmelerle yukarıdaki ile aynı. Çalışır ama kesinlikle hoş değil.

   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

Dürüst olmak gerekirse, yukarıdaki cevapları kullanmak daha iyidir.


5
WHERE yan tümcesi, ORDER BY önce değerlendirildiğinden, bu yanlıştır.
Ben

3
Aşağıdaki kötü cevabımdan ilginç bir şekilde çalındı.
EvilTeach
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.