/** * This version of the query runs better on MySql (but worse on other databases, particularly MS SQL Server) * @param dbConnection the database connection * @return the user count */ private Long runMySqlQuery(final DbConnection dbConnection) { QMembership m = new QMembership("m"); QUser u = new QUser("u"); // Predicate to only include users in their canonical directory (i.e. they are not shadowed) BooleanExpression userIsNotShadowed = userIsNotShadowedPredicate(u); // Query to find only active users that are not shadowed, and that are a member of one or more of the nested // groups in this directory. // Use groupBy() to ensure we count each user only once, even if they are a member of multiple groups final SQLSubQuery uniqueUsersSubQuery = new SQLSubQuery() .from(m).innerJoin(u).on(u.id.eq(m.childId)) .where(u.active.eq(1) .and(m.membershipType.eq("GROUP_USER")) .and(m.directoryId.eq(directoryId)) .and(userIsNotShadowed) .and(m.lowerParentName.in(lowerCaseGroupNames))) .groupBy(m.lowerChildName); final DslExpression<List<String>> uniqueUsers = uniqueUsersSubQuery.list(m.lowerChildName).as("uniqueUsers"); // An outer count(*) query SQLQuery countQuery = dbConnection.newSqlQuery(); countQuery.from(uniqueUsers); return countQuery.singleResult(Wildcard.count); }