如何将any与返回bigint[]值的子查询一起使用?

问题描述 投票:0回答:1

我想从

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)

java jooq
1个回答
0
投票

现有尝试

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();
© www.soinside.com 2019 - 2024. All rights reserved.