【问题标题】:Custom iteration over a JDBC ResultSet对 JDBC ResultSet 的自定义迭代
【发布时间】:2016-03-25 13:10:29
【问题描述】:

我有一个返回(重复)名称列表的结果集,其中包含与该名称关联的一些 sql 条件。这是一个 2 列的结果集。它看起来像这样:

____________________________________
|id                |     data      |
|__________________________________|
|john              | sql1          |
|john              | sql2          |
|adam              | sql1          |
|jack              | sql3          |
|jack              | sql2          |
____________________________________

我想要构建一个如下所示的 SQL 查询:

select *, 'john' as id from table_x where sql1 or sql2
union
select *, 'adam' as id table_x where sql1
union
select *, 'jack' as id from table_x where sql3 or sql2;

这是否可以简单地通过在 while 循环中使用 res.next() 并在那里做一些魔术来实现?我曾想过使用二维数组或 Map 来首先存储结果集,然后对其进行迭代以完成此操作,但想知道是否有更好/更简单的方法来执行此操作。

【问题讨论】:

  • @Andreas:关于检查id 值的变化,你能指出我正确的方向吗?谢谢! :)
  • 将评论转换为答案。
  • 您的数据库平台是什么?我假设 sql1 和 sql2 是谓词(col_name = value)?
  • @slambeth:你是对的。它们是谓词。我正在使用 Impala。
  • 否决票的任何理由?谁投了反对票?

标签: java loops jdbc resultset impala


【解决方案1】:

impala 似乎有一个 group_concat 函数,因此您可以利用它来启动一个步骤。

(table_y 是您的初始结果集来自的表

select id, group_concat(data) as predicates from table_y group by id;

然后简单地遍历它们:

  String sql;  
  while(rs.next()) {
      String rPredicates = rs.getString("predicates").split(",");
      sql = "SELECT *, " + rs.getString("id") + " FROM table_x WHERE "
      sql += rPredicates[0];
      for(int ndx=1; ndx< rPredicates.length; ndx++) {
        sql += " or " + rPredicates[ndx];
      }
      sql += " union ";
    }

这是未经测试的,但你明白了。您可以通过使用 StringUtils.join 或 .collapse 类似的东西来消除几行。那里有许多字符串实用程序类。

如果你足够努力,你也许可以纯粹用 SQL 来产生这个,但这至少会好一点。

编辑: 我来补充一下,你可以为 group_concat 提供一个分隔符,这样你就可以执行这个 SQL 来启动

select id, group_concat(date, ' or ') as predicates from table_y;

那么您就不必组装谓词,只需附加整个内容即可。

【讨论】:

  • 这看起来是个好主意!感谢您的回答:) 我会尝试两者并选择一个。
  • 神圣的 SQL 蝙蝠侠!那个编辑太棒了!我已经有了执行联合的代码(甚至在@Andreas 的回答之前)。使用此查询,我不需要更改代码!想一想,我需要做的就是 RTFM! :P 非常感谢! :D
  • @CodingInCircles 对于此解决方案,一个非常重要的信息是 DBMS 供应商 (Impala)。这是一个很好的特定于供应商的解决方案,而我的回答将适用于所有 DBMS 供应商。 +1 简单的解决方案。
  • 是的,这是非常具体的,因此可能并非所有解决方案都可取。不过,其他一些 DBMS 也具有字符串聚合函数。例如,Oracle 就有一个。
【解决方案2】:

是的,这是可能的。

如果您按id 对查询进行排序,则可以使用普通的ResultSet 循环,并检查id 值的更改。不需要 2D 数组或 Map,只需 StringBuilder 即可增量构建相关 SQL。

String prevId = null;
StringBuilder sql = new StringBuilder();
while (rs.next()) {
    String id   = rs.getString("id");
    String data = rs.getString("data");
    if (id.equals(prevId)) {
        sql.append(" or ");
    } else {
        if (prevId != null)
            sql.append(" union ");
        sql.append("select *, '")
           .append(id) // may need to SQL escape value
           .append("' as id from table_x where ");
        prevId = id;
    }
    sql.append(data);
}

【讨论】:

  • 将 StringJoiner 用于中间的 UNION 可能会很有趣。
  • 谢谢你。我会试一试并在测试后接受它。谢谢! :)
【解决方案3】:

您将收到一个结果集,它是所有 3 个选择的并集。如果要按 id 列进行分类,只需遍历结果集,并根据 id 列的值处理当前行(例如,使用 id 值作为映射的键)。

【讨论】:

  • 我想你误解了我的问题。我已经有一个结果集,它是 id 和 data 列。使用它,我想构建如图所示的查询。
  • 好的,我想我已经接近了。您将构建一个映射,其中 id 列值作为键,数据值列表作为值,然后使用此映射构建每个选择
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
相关资源
最近更新 更多