我有两张桌子。每个客户端有 2 个地址。我需要选择客户名称和地址字符串。我对 jooq 语法、如何为表结果选择 basic_address 和 extra_address 感到困惑
表客户端
id | name | BASIK_OFICE_ID | ADDITIONAL_OFICE_ID
餐桌办公
id | address
结果表
name | basic_address | additional_address
public record ClientAndOfficeData(
String name,
String basic_address,
String additional-address) {}
var content =
context
.select(
CLIENT.NAME,
OFFICE.ADDRESS,
OFFICE.ADDRESS)
.from(CLIENT)
.innerJoin(OFICE)
.on(OFFICE.ID.eq(CLIENT.BASIK_OFFICE_ID))
.or(OFFICE.ID.eq(CLIENT.ADDITIONAL_OFFICE_ID))
.fetchInto(ClientAndOfficeData.class);
}
这并不是一个真正的 jOOQ 问题,而是一个通用的 SQL 问题。您正在尝试执行类似 PIVOT 查询的操作,但仅限固定数量的 2 列。所以,你必须加入表两次:
Office basic = OFFICE.as("basic");
Office additional = OFFICE.as("additional");
var content = context
.select(
CLIENT.NAME,
basic.ADDRESS,
additional.ADDRESS)
.from(CLIENT)
.leftJoin(basic)
.on(basic.ID.eq(CLIENT.BASIK_OFFICE_ID))
.leftJoin(additional)
.on(additional.ID.eq(CLIENT.BASIK_OFFICE_ID))
.fetchInto(ClientAndOfficeData::new);
此方法使用基于生成的代码的类型安全表别名。我使用
LEFT JOIN
而不是 INNER JOIN
,假设办公室 ID 可能是可选的。
另一种也许更简单的方法是使用 隐式连接:
var content = context
.select(
CLIENT.NAME,
CLIENT.basicOffice().ADDRESS,
CLIENT.additionalOffice().ADDRESS)
.from(CLIENT)
.fetchInto(ClientAndOfficeData::new);
这假设您已将外键命名为
BASIC_OFFICE
和 ADDITIONAL_OFFICE
。如果按键名称不同,会有与 basicOffice()
和 additionalOffice()
不同的方法。