2016-06-08 50 views
8

Sto usando UUID v1 come chiave primaria. Vorrei ordinare su UUID v1 timestamp. In questo momento se faccio qualcosa di similePostgresql - ordina per UUID v1 timestamp

select id, title 
from table 
order by id desc 

PostgreSQL non ordinare i record di UUID timestamp, ma dalla rappresentazione di stringa UUID, che finisce con il risultato inaspettato di smistamento nel mio caso.

Mi manca qualcosa o non c'è un modo per farlo in Postgresql?

+0

Forse si è tentato qualcosa di simile? 'selezionare id :: timestamp, titolo dall'ordine di tabella per id :: timestamp desc' – Santhucool

+0

che mi dà un errore. ERRORE: impossibile lanciare il tipo uuid su timestamp – user232343

+0

E 'obbligatorio usare 'uuid v1'? Ho provato 'uuid_generate_v4' e ho semplicemente provato la tua query funziona perfettamente. – Santhucool

risposta

10

Il timestamp è una delle parti di un UUID v1. Viene memorizzato in formato esadecimale a centinaia di nanosecondi dal 1582-10-15 00:00. Questa funzione estrae il timestamp:

create or replace function uuid_v1_timestamp (_uuid uuid) 
returns timestamp with time zone as $$ 

    select 
     to_timestamp(
      (
       ('x' || lpad(h, 16, '0'))::bit(64)::bigint::double precision - 
       122192928000000000 
      )/10000000 
     ) 
    from (
     select 
      substring (u from 16 for 3) || 
      substring (u from 10 for 4) || 
      substring (u from 1 for 8) as h 
     from (values (_uuid::text)) s (u) 
    ) s 
    ; 

$$ language sql immutable; 

select uuid_v1_timestamp(uuid_generate_v1()); 
     uuid_v1_timestamp  
------------------------------- 
2016-06-16 12:17:39.261338+00 

122192928000000000 è l'intervallo tra l'inizio del calendario gregoriano e il timestamp Unix.

Nella tua query:

select id, title 
from t 
order by uuid_v1_timestamp(id) desc 

Per migliorare le prestazioni di un indice può essere creato su che:

create index uuid_timestamp_ndx on t (uuid_v1_timestamp(id)); 
+0

E se si desidera semplicemente ordinare dal timestamp "raw" (e non si preoccupa di convertirlo in unix timestamp di epoca)? –