Правильная сортировка разбитых на страницы результатов в oracle SQL - PullRequest
0 голосов
/ 16 марта 2020

У меня есть реализация пагинации на стороне сервера datatables. Построитель запросов выглядит следующим образом:

public static String buildPaginatedQueryForOracle(String baseQuery, PaginationCriteria paginationCriteria) {

        StringBuilder sb = new StringBuilder(
                "SELECT * FROM (SELECT FILTERED_ORDERED_RESULTS.*, COUNT(1) OVER() total_records, ROWNUM AS RN FROM (SELECT BASEINFO.* FROM ( #BASE_QUERY# ) BASEINFO ) FILTERED_ORDERED_RESULTS #WHERE_CLAUSE# #ORDER_CLASUE# ) WHERE RN > (#PAGE_NUMBER# * #PAGE_SIZE#) AND RN <= (#PAGE_NUMBER# + 1) * #PAGE_SIZE# ");
        String finalQuery = null;

        int pageNo = paginationCriteria.getPageNumber() / paginationCriteria.getPageSize();
        paginationCriteria.setPageNumber(pageNo);

        if (!AppUtil.isObjectEmpty(paginationCriteria)) {
            finalQuery = sb.toString().replaceAll("#BASE_QUERY#", baseQuery)
                    .replaceAll("#WHERE_CLAUSE#",
                            ((AppUtil.isObjectEmpty(paginationCriteria.getFilterByClause())) ? "" : " WHERE ")
                                    + paginationCriteria.getFilterByClause())
                    .replaceAll("#ORDER_CLASUE#", paginationCriteria.getOrderByClause())
                    .replaceAll("#PAGE_NUMBER#", paginationCriteria.getPageNumber().toString())
                    .replaceAll("#PAGE_SIZE#", paginationCriteria.getPageSize().toString());
        }
        return (null == finalQuery) ? baseQuery : finalQuery;
    }

где base_query - обычная строка из уровня dao-impl. Это делает работу хорошо. Однако, когда я хочу отсортировать результаты по cnt в предложении order (в этом конкретном случае cnt подсчитывает строки другой таблицы, связанные с каждой строкой в ​​первой таблице, как это)

SELECT *
  FROM (
       SELECT FILTERED_ORDERED_RESULTS.*,
              COUNT(1) OVER() TOTAL_RECORDS
         FROM (
              SELECT BASEINFO.*,
                     ROWNUM AS RN
                FROM (
                     SELECT A.ID_LIST            AS ID,
                            A.NAME,
                            A.DATE_CREATE        AS DATECREATE,
                            A.DATE_UPDATE        AS DATEUPDATE,
                            A.USER_ID            AS USERID,
                            A.TYPE,
                            NVL(
                                   B.CNT, 0
                            )        CNT
                       FROM MAP_S_LIST_ARTS                                                           A
                       LEFT JOIN (
                            SELECT ID_LIST,
                                   COUNT(*) CNT
                              FROM MAP_LIST_ARTS
                             GROUP BY ID_LIST
                     )        B ON A.ID_LIST = B.ID_LIST
                      ORDER BY A.ID_LIST DESC
              ) BASEINFO
       ) FILTERED_ORDERED_RESULTS
        ORDER BY CNT DESC
)
 WHERE RN > (:PAGE * 5) AND RN <= (:PAGE + 1) * 5 

Что Я понял, что сначала он берет первые 5 строк в другой сортировке (по умолчанию это id), а затем применяет сортировку по cnt только к ним. например, если я получу страницу с 5 строками, она будет сортироваться только среди них, хотя у меня есть другие страницы. Что я могу сделать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...