Spring 使用 GROUP BY 和 ORDER BY 的本机查询也分页

Spring native query with GROUP BY and ORDER BY also pagination

如果我以更“复杂”的方式进行本机查询(使用 PostgreSQL),我需要对数据进行分组以应用 ORDER BY 子句怎么办?好吧,使用本机查询(如 here 所解释的那样),ORDER BY 属性被放置在查询的末尾,这会引发 SQL 语法错误(当然)导致 ORDER BY 应该保留在 BEFORE我的分页子句。

@Query(
        " SELECT * FROM (" +
                "SELECT CAST(t.id AS VARCHAR) AS id, t.name, CAST(COUNT(p.id) AS SMALLINT) AS usedByProjectsCount " +
                "FROM tag t " +
                "LEFT JOIN project_tag pt ON pt.tag_id = t.id " +
                "LEFT JOIN project p ON p.id = pt.project_id " +
                "GROUP BY t.id, t.name) AS t " +
                "ORDER BY #pageable " +
                "LIMIT :limit OFFSET :offset ",
        countQuery = " SELECT COUNT(*) FROM (" +
                "SELECT CAST(t.id AS VARCHAR) AS id, t.name, CAST(COUNT(p.id) AS SMALLINT) AS usedByProjectsCount " +
                "FROM tag t " +
                "LEFT JOIN project_tag pt ON pt.tag_id = t.id " +
                "LEFT JOIN project p ON p.id = pt.project_id " +
                "GROUP BY t.id, t.name) AS t ",
        nativeQuery = true
    )

我已经尝试将 #pageable 放在末尾,但我收到相同的错误消息。

继续,Spring 生成我的查询,如:SELECT * FROM (SELECT CAST(t.id AS VARCHAR) AS id, t.name, CAST(COUNT(p.id) AS SMALLINT) AS usedByProjectsCount FROM tag t LEFT JOIN project_tag pt ON pt.tag_id = t.id LEFT JOIN project p ON p.id = pt.project_id GROUP BY t.id, t.name) AS t ORDER BY {#pageable} LIMIT ? OFFSET ? , t.usedByProjectsCount desc

我需要:SELECT * FROM (SELECT CAST(t.id AS VARCHAR) AS id, t.name, CAST(COUNT(p.id) AS SMALLINT) AS usedByProjectsCount FROM tag t LEFT JOIN project_tag pt ON pt.tag_id = t.id LEFT JOIN project p ON p.id = pt.project_id GROUP BY t.id, t.name) AS t ORDER BY t.usedByProjectsCount desc LIMIT ? OFFSET ? {#pageable}

我知道 {#pageable} 属性应该留在那里,这样我的页面值就可以放在正确的变量中。

无论如何,我们将不胜感激。

在我的一个项目中,我有一个本地查询,只是将可分页放在里面。

@Query(
    value = "SELECT * " +
            "  FROM (SELECT CAST(t.id AS VARCHAR) AS id, " +
            "               t.name, " + 
            "                CAST(COUNT(p.id) AS SMALLINT) AS usedByProjectsCount " +
            "          FROM tag t " +
            "          LEFT JOIN project_tag pt ON pt.tag_id = t.id " +
            "          LEFT JOIN project p ON p.id = pt.project_id " +
            "         GROUP BY t.id, t.name) AS t ",

    countQuery = " SELECT COUNT(*) " + 
                 "        FROM (SELECT 1 " +
                 "                FROM tag t " +
                 "                LEFT JOIN project_tag pt ON pt.tag_id = t.id " +
                 "                LEFT JOIN project p ON p.id = pt.project_id " +
                 "               GROUP BY t.id, t.name) AS t ",
    nativeQuery = true)
Page<CustomProjection> customQuery(Pageable pageable)

然后使用所需的 pageRequest 调用您的方法。

Pageable pageRequest = PageRequest.of(0, 10, Sort.of(Order.desc("usedByProjectsCount"))