Spring Data - разбиение на страницы собственного запроса, использующего CTE - PullRequest
0 голосов
/ 25 февраля 2020

Я использую Spring и Postgres. У меня есть два связанных объекта: UserProfile и Post, которые имеют отношение один ко многим. Я хочу заказать UserProfiles по количеству постов.

Основной запрос c выглядит следующим образом (и работает как нужно):

WITH num_posts AS (SELECT f.profile_id, COUNT(1) post_count FROM post f GROUP BY profile_id) SELECT DISTINCT * FROM profiles INNER JOIN num_posts ON profile_id=user_id ORDER BY post_count DESC

Я хочу получить результаты как страницу Spring. Функция репозитория выглядит следующим образом:

@Query(value = "WITH num_posts AS (SELECT f.profile_id, COUNT(1) post_count FROM post f GROUP BY profile_id) SELECT DISTINCT * FROM profiles INNER JOIN num_posts ON profile_id=user_id ORDER BY post_count DESC",
countQuery = "WITH num_posts AS (SELECT f.profile_id, COUNT(1) post_count FROM post f GROUP BY profile_id) SELECT DISTINCT count(*) FROM profiles INNER JOIN num_posts ON profile_id=user_id ORDER BY post_count DESC",
nativeQuery = true)
Page<UserProfile> findAllWithPageableOrderByPosts(Pageable pageable);

Если результаты меньше количества элементов на странице (например, 10 профилей, но 15 элементов на странице), проблема не возникает, и результаты возвращаются. Однако если общие результаты превышают количество элементов на странице (например, 20 профилей, но 15 элементов на странице), возникает следующая ошибка:

ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list

Насколько я могу судить, проблема, похоже, заключается в countQuery возможно связан с count (). Однако я не нашел соответствующих ответов в своих поисках. Любая помощь приветствуется.

1 Ответ

0 голосов
/ 25 февраля 2020

Это ваш второй запрос, который не имеет смысла (для ясности я опускаю WITH):

SELECT DISTINCT count(*)
FROM profiles
   INNER JOIN num_posts ON profile_id = user_id
ORDER BY post_count DESC;

Первый , который вы считаете (который, кстати, производит одно число), затем вы хотите объединить равные значения, а затем вы хотите отсортировать результат по чему-то, что может быть различным для каждой строки, которая объединена в одну.

Если вы хотите общее количество, сделайте

SELECT count(DISTINCT *)
FROM profiles
   INNER JOIN num_posts ON profile_id = user_id;
...