JDBC 结果集的自定义迭代
Custom iteration over a JDBC ResultSet
我有一个结果集,其中 returns 一个(重复的)名称列表以及与该名称相关联的一些 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 来首先存储结果集,然后对其进行迭代以完成此操作,但想知道是否有任何 better/easier 方法可以做到这一点。
您将收到一个结果集,它是所有 3 个选择的并集。如果你想按 id 列分类,你只需遍历结果集,并根据 id 列的值处理当前行(例如,使用 id 值作为映射的键)。
是的,有可能。
如果按 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);
}
impala 似乎有一个 group_concat 函数,因此您可以利用它来阐明一个步骤。
(table_y 是 table 您的初始结果集来自
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 simlar 来删除几行。那里有很多字符串实用程序 类。
如果你足够努力,你也许可以纯粹用 SQL 来制作这个,但这至少要好一些。
编辑:
我会把这个放在一起,你可以为 group_concat 提供一个分隔符,这样你就可以执行这个 SQL 来开始
select id, group_concat(date, ' or ') as predicates from table_y;
那么您就不必 assemble 谓词,只需附加整个内容即可。
我有一个结果集,其中 returns 一个(重复的)名称列表以及与该名称相关联的一些 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 来首先存储结果集,然后对其进行迭代以完成此操作,但想知道是否有任何 better/easier 方法可以做到这一点。
您将收到一个结果集,它是所有 3 个选择的并集。如果你想按 id 列分类,你只需遍历结果集,并根据 id 列的值处理当前行(例如,使用 id 值作为映射的键)。
是的,有可能。
如果按 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);
}
impala 似乎有一个 group_concat 函数,因此您可以利用它来阐明一个步骤。
(table_y 是 table 您的初始结果集来自
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 simlar 来删除几行。那里有很多字符串实用程序 类。
如果你足够努力,你也许可以纯粹用 SQL 来制作这个,但这至少要好一些。
编辑: 我会把这个放在一起,你可以为 group_concat 提供一个分隔符,这样你就可以执行这个 SQL 来开始
select id, group_concat(date, ' or ') as predicates from table_y;
那么您就不必 assemble 谓词,只需附加整个内容即可。