2014-11-20 103 views
22

Il mio requisito è quello di ottenere l'ultimo ordine di ogni cliente e quindi ottenere i primi 100 record.Come selezionare le prime 100 righe in Oracle?

Ho scritto una query come sotto per ottenere gli ultimi ordini per ogni cliente. La query interna funziona correttamente. Ma non so come ottenere i primi 100 in base ai risultati.

SELECT * FROM (
     SELECT id, client_id, ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
     FROM order 
    ) WHERE rn=1 

Qualche idea? Grazie.

+0

Giusto per chiarire: vuoi i primi 100 per ogni cliente oi primi 100 clienti? –

+0

Desidero l'ultimo ordine dei primi 100 client. – user2321728

risposta

20

Supponendo che create_time contiene il tempo l'ordine è stato creato, e si desidera che i 100 clienti con gli ultimi ordini, è possibile:

  • aggiungere il create_time nella query più interna
  • fine i risultati della query esterna di la create_time desc
  • aggiungere una query più esterno che filtra le prime 100 righe utilizzando ROWNUM

Query:

SELECT * FROM (
    SELECT * FROM (
     SELECT 
      id, 
      client_id, 
      create_time, 
      ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
     FROM order 
    ) 
     WHERE rn=1 
     ORDER BY create_time desc 
) WHERE rownum <= 100 

UPDATE per Oracle 12c

Con la versione 12.1, Oracle ha introdotto "real" Top-N queries. Utilizzando il nuovo FETCH FIRST... sintassi, è anche possibile utilizzare:

SELECT * FROM (
    SELECT 
     id, 
     client_id, 
     create_time, 
     ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
    FROM order 
) 
    WHERE rn = 1 
    ORDER BY create_time desc 
    FETCH FIRST 100 ROWS ONLY) 
+0

In realtà sono confuso, se non metto un altro SELECT sopra la mia prima query, ma scrivo ROWNUM <101 accanto a rn = 1. Perché i due risultati sono diversi? – user2321728

+0

'SELECT * FROM ( SELEZIONARE id, client_id, create_time, ROW_NUMBER() OVER (partizione CON ORDINANZA client_id BY create_time DESC) rn dall'ordine ) DOVE rn = 1, rownum <= 100 ORDER BY create_time desc' – user2321728

+1

Perché in questo caso, non stai ordinando le tue righe da create_time - il tuo set di risultati è ordinato a caso, e prendi solo il primo 100; questo è essenzialmente un campione casuale. –

-2

Prova questo:

SELECT * 
FROM (SELECT * FROM (
    SELECT 
     id, 
     client_id, 
     create_time, 
     ROW_NUMBER() OVER(PARTITION BY client_id ORDER BY create_time DESC) rn 
    FROM order 
) 
    WHERE rn=1 
    ORDER BY create_time desc) alias_name 
WHERE rownum <= 100 
ORDER BY rownum; 

O SUPERIORE:

SELECT TOP 2 * FROM Customers; //But not supported in Oracle 

NOTA: Suppongo che la query interna va bene. Si prega di condividere il risultato di questo.

+1

oracle hanno selezionato top ???? id non la penso così –

+1

Ha dato errore come "ORA-00923: parola chiave FROM non trovata dove previsto." Non penso che TOP funzioni. – user2321728

+4

Oracle non supporta TOP –

15

si dovrebbe utilizzare rownum in Oracle per fare ciò che cercate

where rownum <= 100 

Vedi anche quelle risposte per aiutarvi a

limit in oracle

select top in oracle

select top in oracle 2

+0

Ci sono due modi per farlo. SELEZIONARE * FROM (SELECT * FROM ( ID SELECT, id_cliente, ROW_NUMBER() OVER (PARTITION BY client_id ORDINA BY create_time DESC) rn FROM ordine ) WHERE rn = 1) WHERE ROWNUM <101'O 'SELEZIONA * DA ( ID SELEZIONA , client_id, ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY create_time DESC) rn FROM order ) WHERE rn = 1 AND ROWNUM <101' I test questi due, i risultati sono diversi. – user2321728

0

primi 10 clienti inseriti in db (clienti tabella):

select * from clienti dove CUSTOMER_ID < = (select min (customer_id) +10 da parte dei clienti)

Ultimi 10 clienti inseriti in db (clienti tabella):

select * from clienti dove customer_id> = (selezionare max (customer_ id) -10 dai clienti)

Spero che questo aiuti ....

+0

Le tue query presumono che non ci siano lacune in customer_id. Se tale ipotesi è errata (poiché le righe sono state eliminate, poiché la sequenza utilizzata per popolare il PK utilizza la memorizzazione nella cache/un incremento maggiore di 1/...), restituirà un numero di righe inferiore a quello richiesto. –

Problemi correlati