我想从
original_content
获取所有行,其中 id
位于 pipeline_status.oc_version
列,其中 pipeline_status.uuid
=4f3164b9-6fde-45d6-bd58-86308473b0dc
- 我有 2 个 PostgreSQL 查询,它们给了我预期的结果,我想翻译他们中的任何一个到 jOOQ:
SELECT oc.* FROM original_content oc
WHERE oc.id = ANY(SELECT unnest(pipeline_status.oc_version) FROM pipeline_status WHERE pipeline_status.uuid='4f3164b9-6fde-45d6-bd58-86308473b0dc' AND pipeline_status.oc_version IS NOT NULL)
-- or
SELECT oc.* FROM original_content oc
WHERE oc.id = ANY(array(SELECT ps.oc_version FROM pipeline_status ps WHERE ps.uuid='4f3164b9-6fde-45d6-bd58-86308473b0dc' AND pipeline_status.oc_version IS NOT NULL))
我生成了 DSL,并且做了类似的事情
dslContext.select(
ORIGINAL_CONTENT.asterisk()
)
.from(ORIGINAL_CONTENT)
.where(ORIGINAL_CONTENT.ID.eq(
DSL.any(DSL.select(PIPELINE_STATUS.OC_VERSION).from(PIPELINE_STATUS).where(PIPELINE_STATUS.UUID.eq(pipelineUuid)))
)
)
但是,我收到错误:
无法解析方法“eq(QuantifiedSelect
>)”
我该如何解决这个问题?
我的SQL:
create table public.pipeline_status
(
uuid varchar(50) not null primary key,
oc_version bigint[]
);
create table original_content
(
id bigserial primary key,
name varchar(50) not null,
created_at timestamp default (now() AT TIME ZONE 'UTC'::text) not null
);
insert into pipeline_status (uuid, oc_version)
values ('4f3164b9-6fde-45d6-bd58-86308473b0dc', '{1020,1021}');
insert into original_content (id, name, created_at)
OVERRIDING SYSTEM VALUE
values (1001, 'Name2', '2024-03-22 06:33:12.574244'),
(1021, 'Name2', '2024-03-22 07:33:32.574244'),
(1020, 'Name1', '2024-03-22 09:33:31.574244'),
(1040, 'Name1', '2024-03-22 07:33:51.574244'),
(1002, 'Name3', '2024-03-22 07:33:13.574244');
SELECT oc.* FROM original_content oc
WHERE oc.id = ANY(SELECT unnest(pipeline_status.oc_version) FROM pipeline_status WHERE pipeline_status.uuid='4f3164b9-6fde-45d6-bd58-86308473b0dc' AND pipeline_status.oc_version IS NOT NULL)
在
UNNEST()
子句中使用 SELECT
是一个非常奇怪的、历史悠久的 PostgreSQL 特定功能,jOOQ 不支持开箱即用,尽管您显然可以使用 plain SQL 模板 来让它工作,例如
DSL.field("unnest({0})",
ORIGINAL_CONTENT.ID.getDataType(),
PIPELINE_STATUS.OC_VERSION
);
oc.id = ANY(array(SELECT ps.oc_version ..))
方法对我来说似乎是错误的,但我认为它是有效的,因为 PostgreSQL 不能正确支持多维数组。 ARRAY(SELECT array_column)
表达式应该生成 BIGINT[][]
类型,但这在 PostgreSQL 中不存在,它只是将其扁平化。 jOOQ 不支持这一点,它假设正确支持多维数组,因此当您想要 Field<Long[][]>
类型时,您会得到错误的 Field<Long[]>
类型。
换句话说,jOOQ 不支持这两种 PostgreSQL 特定的怪癖。
但是我会将您的查询的 SQL 版本重写为:
SELECT *
FROM original_content oc
EXISTS (
SELECT 1
FROM pipeline_status pc
WHERE pc.uuid = '4f3164b9-6fde-45d6-bd58-86308473b0dc'
AND pc.oc_version IS NOT NULL
AND oc.id = ANY(pc.oc_version)
)
与jOOQ:
ctx.selectFrom(ORIGINAL_CONTENT)
.where(exists(
selectOne()
.from(PIPELINE_STATUS)
.where(PIPELINE_STATUS.UUID.eq("4f3164b9-6fde-45d6-bd58-86308473b0dc"))
.and(PIPELINE_STATUS.OC_VERSION.isNotNull())
.and(ORIGINAL_CONTENT.ID.eq(any(PIPELINE_STATUS.OC_VERSION)))
))
.fetch();