Sig*_*Sig 5 postgresql join cast array uuid
如何将text
s 数组转换为UUID
s数组?
我需要join
在两个表之间做一个:users
和projects
。
该users
表有一个名为的数组字段,project_ids
其中包含作为文本的项目 ID。
该projects
表有一个名为 的 UUID 字段id
。
我最初的想法是一个查询看起来像:
SELECT * FROM projects
JOIN users ON
projects.id = ANY(users.project_ids)
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为users.project_ids
不是,UUID
所以我试过:
projects.id = ANY(users.project_ids::uuid[])
Run Code Online (Sandbox Code Playgroud)
乃至:
projects.id = ANY(ARRAY[users.project_ids]::uuid[])
Run Code Online (Sandbox Code Playgroud)
但没有一个有效:
Run Code Online (Sandbox Code Playgroud)ERROR: invalid input syntax for type uuid: ""
更新
@a_horse_with_no_name 绝对正确。最好的选择应该是使用一组 UUID。
现在的问题是我如何可以改变的阵列text
到阵列uuid
?
该users
表当前为空(0 条记录)。
我试过了
ALTER TABLE "users" ALTER COLUMN "project_ids" SET DATA TYPE UUID USING "project_ids"::uuid[];
Run Code Online (Sandbox Code Playgroud)
这产生
错误:无法将列“product_ids”的 USING 子句的结果自动转换为类型 uuid 提示:您可能需要添加显式转换。
ALTER TABLE "users" ALTER COLUMN "product_ids" SET DATA TYPE UUID USING "product_ids"::UUID;
我也试过
ALTER TABLE "users" ALTER COLUMN "project_ids" SET DATA TYPE UUID[] USING "project_ids"::uuid[];
Run Code Online (Sandbox Code Playgroud)
这产生
错误:列“project_ids”的默认值无法自动转换为类型 uuid[]
该列默认设置为空数组。
我正在运行 PG 10.4 版,project_ids
目前是text[] nullable
.
正如已评论的那样,该列project_ids
应该是uuid[]
,这可以排除该问题。这也会更加高效。
要更改(如您所断言的列中没有非法数据):
ALTER TABLE users ALTER COLUMN project_ids DROP DEFAULT;
ALTER TABLE users
ALTER COLUMN project_ids SET DATA TYPE uuid[] USING project_ids::uuid[];
Run Code Online (Sandbox Code Playgroud)
你有uuid
而不是uuid[]
错误。
和这个:
错误:列“product_ids”的默认值无法自动转换为 uuid[] 类型
.. 意味着您为该列设置了默认值。该表达式无法自动转换。在更改类型之前将其删除。您可以稍后添加新的DEFAULT
。
在原始情况下,有效的解决方法是在转换之前从数组中删除空字符串(需要 Postgres 9.3+):array_remove()
SELECT *
FROM users u
JOIN projects p ON p.id = ANY(array_remove(u.project_ids, '')::uuid[]);
Run Code Online (Sandbox Code Playgroud)
...在调查了为什么该列中可能有空刺之后text[]
。
有关的:
[INNER] JOIN
查询中的 会从结果中删除没有有效项目的用户projects_ids
。通常,您也想保留这些:使用LEFT [OUTER] JOIN
替代(与users
第一个)。
无论哪种方式,折叠JOIN
都会重复条目,这可能会或可能不会如您所愿。如果您想表示重复的条目,请在连接之前取消嵌套。
如果您的目标只是将 ID 数组解析为项目名称数组,您还需要保留数组元素的原始顺序:
SELECT *
FROM users u
LEFT JOIN LATERAL (
SELECT ARRAY(
SELECT project_name -- use the actual column(s) of your case
FROM unnest (array_remove(u.project_ids, '')::uuid[]) WITH ORDINALITY AS p(id, ord)
JOIN projects USING (id)
ORDER BY ord
)
) p(projects) ON true;
Run Code Online (Sandbox Code Playgroud)
db<>fiddle这里(松散地基于McNets 的 fiddle)
有关的:
归档时间: |
|
查看次数: |
19640 次 |
最近记录: |