Postgres从JSON转换为UUID

时间:2018-12-01 05:01:46

标签: postgresql

我有两个非常简单的表sessions,其中有一个json列,如下所示:

+----+-------------------------------------------------------+
| id |                         data                          |
+----+-------------------------------------------------------+
|  1 | { "user_id": "bc2166dd-ca1d-41c6-9c66-610f844ca139" } |
+----+-------------------------------------------------------+

还有一个users表,如下所示:

+--------------------------------------+--------------------+
|                  id                  |       email        |
+--------------------------------------+--------------------+
| bc2166dd-ca1d-41c6-9c66-610f844ca139 | foobar@example.com |
+--------------------------------------+--------------------+

是否可以像这样联接json列类型的内容?

with recursive active_sessions AS (
  select
  data->'users_id' as sid
  from sessions
)

select *
from active_sessions
join users ON active_sessions.sid = users.id
where sid is not null;

在我的基本尝试中,我被卡住了,似乎无法获得能够在联接中使用的json文本,我得到了这个错误:

[22P02] ERROR: invalid input syntax for uuid: ""bc2166dd-ca1d-41c6-9c66-610f844ca139""

请注意双引号...?

我还尝试过将user_id强制转换为(data->'user_id')::uuid,但是没有运气。

1 个答案:

答案 0 :(得分:5)

问题在于->运算符返回JSON,这就是为什么您返回带引号的字符串作为字符串的一部分而不是您期望的字符串的原因。查看https://www.postgresql.org/docs/9.5/functions-json.html中的详细信息。

您应该改用->>运算符,因为它将返回整数或文本值。返回的文本将不包含引号。然后,您可以将文本转换为uuid,Postgres会识别出来。

SQL小提琴:http://sqlfiddle.com/#!17/d9e06/3/0

create table sessions (id integer, data json);
insert into sessions values(1, ' { "user_id": "bc2166dd-ca1d-41c6-9c66-610f844ca139" }');
create table users (id uuid, email text);
insert into users values('bc2166dd-ca1d-41c6-9c66-610f844ca139','a@b.com');

--query using ->> operator to return an integer or text instead of JSON
select (data->>'user_id')::uuid 
, * 
from sessions 
join users on (data->>'user_id')::uuid = users.id;