【问题标题】:Union query with multiple selects post java 8带有多个选择的联合查询发布 java 8
【发布时间】:2018-08-06 02:39:50
【问题描述】:

这是一个我想在 MySQL 中尝试的查询

SELECT A.x
FROM A
WHERE A.y = 'P'
UNION
SELECT A.x
FROM A
WHERE A.y = 'Q'

以上是我正在尝试的原始查询的精简版,更简单的版本。在我的原始查询中,每个SELECT 语句都涉及多个带有INNER JOIN 的表

如果我需要查询的表“A”的“y”列中的可能值数是“n”,那么我的查询将涉及对“n”SELECT 语句执行“n-1”联合

我知道 JOOQ 可以合并多个 SELECT 语句。但是有没有一种好的方法来完成这篇 Java 8 风格的文章?也许使用 Steam.collect()?

这就是我所拥有的,但我想知道我是否可以做得更好

String firstValueToQuery = valuesToQuery.get(0);
Select<Record5<UUID, UUID, String, Integer, String>> selectQuery =  getSelectQueryForValue(firstValueToQuery);
valuesToQuery.stream()
             .skip(1)
             .forEach(valueToQuery -> selectQuery.unionAll(getSelectQueryForValue(valueToQuery)));
selectQuery.fetchStream();

这是我如何实现getSelectQueryForValue

private Select<Record5<UUID, UUID, String, Integer, String>> getSelectQueryForValue(String valueToQuery) {
        return jooq.select(
                A.P,
                A.Q,
                A.R,
                A.S,
                A.T)
                .from(A)
                .where(A.Y.eq(valueToQuery));
    }

PS:我知道我宁愿使用下面的“IN”子句

SELECT A.x
FROM A
WHERE A.y IN ('P','Q',...)

但就我目前在数据库中的数据分布而言,MySQL 使用的是次优查询计划。因此使用 UNION 以便数据库通过使用正确的索引隐式地倾向于更快的查询计划

【问题讨论】:

  • 我很好奇你假设一个巨大的联合查询将胜过一个 IN 谓词。你介意详细说明一下吗? (恭喜第一个问题真的很酷,顺便说一句)

标签: java mysql java-stream jooq


【解决方案1】:

这里的惯用方法如下(使用 JDK 9 API):

try (Stream<Record5<UUID, UUID, String, Integer, String>> stream = valuesToQuery
        .stream()
        .map(this::getSelectQueryForValue)
        .reduce(Select::union)
        .stream() // JDK 9 method
        .flatMap(Select::fetchStream)) {
    ...
}

它使用了有用的Optional.stream() 方法,该方法是在 JDK 9 中添加的。在 JDK 8 中,您可以这样做:

valuesToQuery
    .stream()
    .map(this::getSelectQueryForValue)
    .reduce(Select::union)
    .ifPresent(s -> {
        try (Stream<Record5<UUID, UUID, String, Integer, String>> stream = 
             s.fetchStream()) {
            ...
        }
    })

I blogged about this in more detail here.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 2016-12-03
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多