使用 jooq 从 select 中排除提供的值

Exclude supplied values from select using jooq

我正在尝试使用 jOOQ 查找给定列表中存在但不存在于数据库 table 中的值列表。

例如,我的列表中有值 1234

数据库中已有 12 的条目。

我正在寻找一个 jOOQ 查询,它将 return 我的结果 3,4.

我知道这可以通过 sql 中的 VALUESEXCEPT 术语来完成,我知道这些存在于 jOOQ 中,并且一直在尝试复制它们,然而,解释 here 使用值的简单案例使用静态列表(而我的将以编程方式提供),我不确定 that 是否是原因,或者如果它是更通用的语法。我还没有在 jOOQ 在线找到 except 的好例子。

我尝试过的:

List<String> valuesList
create.select()
    .from(values(getRowsFromList(valuesList)))
    .except(select(TABLE.VALUE).from(TABLE))
    .fetch(TABLE.VALUE)

values 需要一个 vararg RowN 对象,所以我正在转换值

private RowN[] getRowsFromList(List<String> rows)
{
    return rows.stream().map(DSL::row).toArray(RowN[]::new);
}

错误:

java.lang.IllegalArgumentException: Field ("public"."table"."value") is not contained in Row ("v"."c1")

使用 java 11,postgres 11 后端,jooq 3.13.12

您的查询没有 table.value 列。它甚至没有 value 列。当您使用集合操作时,投影的列名是集合操作的第一个子查询的列名,例如:

SELECT a
FROM (VALUES (1), (2), (3), (4)) AS t (a)
EXCEPT
SELECT value
FROM table

这会生成一个 table,其中有一列 a。但是您没有为第一个 EXCEPT 子查询的列命名,因此名称未定义(jOOQ and/or PostgreSQL 可能会生成一个,但我不会依赖它)。

解决方案是使用派生列列表(我在上面使用的 AS t (a) 语法)命名您的列。这应该可以解决您的查询:

create.select()
    .from(values(getRowsFromList(valuesList)).as("t", TABLE.VALUE.getName())
    .except(select(TABLE.VALUE).from(TABLE))
    .fetch(TABLE.VALUE)