Postgresql - sort by UUID v1 timestamp

余生长醉 提交于 2019-12-04 20:14:03

问题


I am using UUID v1 as the primary key. I would like to sort on UUID v1 timestamp. Right now if I do something like

select id, title 
from table 
order by id desc

Postgresql does not sort records by UUID timestamp, but by UUID string representation, which ends up with unexpected sorting result in my case.

Am I missing something, or there is not a built in way to do this in Postgresql?


回答1:


The timestamp is one of the parts of a v1 UUID. It is stored in hex format as hundreds nanoseconds since 1582-10-15 00:00. This function extracts the 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 is the interval between the start of the Gregorian calendar and the Unix timestamp.

In your query:

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

To improve performance an index can be created on that:

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


来源:https://stackoverflow.com/questions/37713131/postgresql-sort-by-uuid-v1-timestamp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!