错误的分区列表"列表中的最大表达式数为1000"

时间:2018-06-05 18:53:07

标签: java mysql sql oracle hql

我在HQL查询中传递了一个包含1000多个元素的列表 得到了这个错误

#<app_root>/app/javascript/application.js
const images = require.context('../images/', true)

我在Stackoverflow上阅读了几篇帖子,建议将列表分成几个子列表。

maximum number of expressions in a list is 1000

我是HQL查询的新手,有人可以告诉我如何将 Query query = session.createQuery( "SELECT r.subject, COUNT(DISTINCT ss.id), COUNT(DISTINCT r.uid)\n" + "FROM " + R.class.getName() + " r\n" + "," + SS.class.getName() + " ss\n" + "WHERE r.id = ss.id\n" + "AND r.uid in (:listMoreThan1000)\n" + "GROUP BY r.subject\n" ); query.setParameterList("listMoreThan1000", listMoreThan1000); List<Object[]> rows = query.list(); // code to parse the rows 分区到我的代码中的几个子列表中吗?

2 个答案:

答案 0 :(得分:2)

尝试使用元组或可能的子查询。

  • 1000项,例如IN(1,2,3,...,1000)
  • 套数无限制:IN((1),(2),(3),...)*&lt; === NOT REMOVE! *见下文
  • 子查询没有限制:IN(SELECT ...)

答案 1 :(得分:1)

错误很明显,只需将您的巨大列表拆分为小列表而不是将它们传递给您的查询,如果您使用的是Java 8+,则可以使用此方法Divide a list to lists of n size in Java 8 Szymon Stepniak

private static <T> Collection<List<T>> partition(List<T> list, int size) {
    final AtomicInteger counter = new AtomicInteger(0);

    return list.stream()
            .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / size))
            .values();
}

然后您的服务可能如下所示:

List<String> listMoreThan1000 = ...;
int size = 1000;
Collection<List<String>> split = partition(listMoreThan1000, size);
String inClause = "", or = "";
for (int i = 0; i < split.size(); i++) {
    inClause += or + "r.uid in ?" + i;
    or = " OR ";
}
String query = String.format("SELECT r.subject, COUNT(DISTINCT ss.id), COUNT(DISTINCT r.uid)" +
        " FROM %s r, %s ss" +
        " WHERE r.id = ss.id" +
        " AND %s GROUP BY r.subject", R.class.getName(), SS.class.getName(), inClause);

Query query = session.createQuery(query);
for (int i = 0; i < split.size(); i++) {
    query.setParameter("?" + i, split.get(i));
}

List<Object[]> rows = query.list();

您的查询最终应如下所示:

SELECT r.subject, COUNT(DISTINCT ss.id), COUNT(DISTINCT r.uid)
FROM R r, SS ss
WHERE r.id = ss.id
AND r.uid in ?1 OR r.uid in ?2 OR r.uid in ?3 GROUP BY r.subject

请注意这一部分:

r.uid in ?1 OR r.uid in ?2 OR r.uid in ?3

这将检查您的uid是否存在于第一个子列表或2ed子列表中......直到n子列表