DSL 中的 JOOQ 和 PostgreSQL 类型 select
JOOQ and PostgreSQL types in a DSL select
我对 jOOQ 3.8 有疑问。
所以,我在 PostgreSQL 9.5 中有一个 table,类似
CREATE TABLE my_table(
id bigserial,
types my_type[]
)
其中 my_type 是类似
的类型
CREATE TYPE my_type AS(
id smallint,
something text
)
现在,在 jOOQ 3.8 中,我想做一些类似的事情
dsl.selectDistinct(MY_TABLE.ID)
.from(MY_TABLE)
.join(TYPE_TABLE).on(TYPE_TABLE.ID.equal(DSL.any(
MY_TABLE.TYPES.ID
))
.fetch(MY_TABLE.ID);
很明显我MY_TABLE.TYPES.ID
的步骤是错误的。我正在考虑使用 DSL.select(MY_TYPE.ID)...
但显然 my_type 是一种类型,而不是 table。
如何使用 jOOQ 访问类型属性?
如何用 Postgre 解决这个问题SQL
我认为没有一种简单的方法可以将您的 my_type[]
转换为 PostgreSQL 中的 integer[]
类型,为每个值提取 my_type.id
可与 any()
运算符一起使用。
但是您可以使用 UNNEST()
解决此限制,如下所示:
SELECT DISTINCT my_table.id
FROM my_table
CROSS JOIN LATERAL unnest(my_table.types)
以上将产生类似
的结果
id types id something
----------------------------------------------
1 {"(1,a)","(2,b)"} 1 a
1 {"(1,a)","(2,b)"} 2 b
2 {"(1,a)","(2,b)","(3,c)"} 1 a
2 {"(1,a)","(2,b)"} 2 b
2 {"(1,a)","(2,b)"} 3 c
现在这个,你可以再次加入TYPE_TABLE
,如:
SELECT DISTINCT my_table.id
FROM my_table
CROSS JOIN LATERAL unnest(my_table.types) types
INNER JOIN type_table ON type_table.id = types.id
或者,可能表现更好:
SELECT my_table.id
FROM my_table
WHERE EXISTS (
SELECT 1
FROM type_table
JOIN unnest(my_table.types) AS types ON type_table.id = types.id
)
如何用 jOOQ 解决这个问题
jOOQ 的 unnest 支持目前(从版本 3.8 开始)相当简单,即您不会在结果 table 中获得所有类型信息,这就是为什么您需要做一些简单的 SQL 混合。但它肯定是可行的!方法如下:
create().select(MY_TABLE.ID)
.from(MY_TABLE)
.whereExists(
selectOne()
.from(unnest(MY_TABLE.TYPES).as("types",
MY_TYPE.ID.getName(),
MY_TYPE.SOMETHING.getName()
))
.join(TYPE_TABLE)
.on(TYPE_TABLE.ID.eq(field(name("types", MY_TYPE.ID.getName()),
MY_TYPE.ID.getDataType())))
)
.fetch(MY_TABLE.ID);
我对 jOOQ 3.8 有疑问。 所以,我在 PostgreSQL 9.5 中有一个 table,类似
CREATE TABLE my_table(
id bigserial,
types my_type[]
)
其中 my_type 是类似
的类型CREATE TYPE my_type AS(
id smallint,
something text
)
现在,在 jOOQ 3.8 中,我想做一些类似的事情
dsl.selectDistinct(MY_TABLE.ID)
.from(MY_TABLE)
.join(TYPE_TABLE).on(TYPE_TABLE.ID.equal(DSL.any(
MY_TABLE.TYPES.ID
))
.fetch(MY_TABLE.ID);
很明显我MY_TABLE.TYPES.ID
的步骤是错误的。我正在考虑使用 DSL.select(MY_TYPE.ID)...
但显然 my_type 是一种类型,而不是 table。
如何使用 jOOQ 访问类型属性?
如何用 Postgre 解决这个问题SQL
我认为没有一种简单的方法可以将您的 my_type[]
转换为 PostgreSQL 中的 integer[]
类型,为每个值提取 my_type.id
可与 any()
运算符一起使用。
但是您可以使用 UNNEST()
解决此限制,如下所示:
SELECT DISTINCT my_table.id
FROM my_table
CROSS JOIN LATERAL unnest(my_table.types)
以上将产生类似
的结果id types id something
----------------------------------------------
1 {"(1,a)","(2,b)"} 1 a
1 {"(1,a)","(2,b)"} 2 b
2 {"(1,a)","(2,b)","(3,c)"} 1 a
2 {"(1,a)","(2,b)"} 2 b
2 {"(1,a)","(2,b)"} 3 c
现在这个,你可以再次加入TYPE_TABLE
,如:
SELECT DISTINCT my_table.id
FROM my_table
CROSS JOIN LATERAL unnest(my_table.types) types
INNER JOIN type_table ON type_table.id = types.id
或者,可能表现更好:
SELECT my_table.id
FROM my_table
WHERE EXISTS (
SELECT 1
FROM type_table
JOIN unnest(my_table.types) AS types ON type_table.id = types.id
)
如何用 jOOQ 解决这个问题
jOOQ 的 unnest 支持目前(从版本 3.8 开始)相当简单,即您不会在结果 table 中获得所有类型信息,这就是为什么您需要做一些简单的 SQL 混合。但它肯定是可行的!方法如下:
create().select(MY_TABLE.ID)
.from(MY_TABLE)
.whereExists(
selectOne()
.from(unnest(MY_TABLE.TYPES).as("types",
MY_TYPE.ID.getName(),
MY_TYPE.SOMETHING.getName()
))
.join(TYPE_TABLE)
.on(TYPE_TABLE.ID.eq(field(name("types", MY_TYPE.ID.getName()),
MY_TYPE.ID.getDataType())))
)
.fetch(MY_TABLE.ID);