【问题标题】:Write sql native query with left join and pagination in hibernate (springboot) [duplicate]在休眠(springboot)中使用左连接和分页编写sql本机查询[重复]
【发布时间】:2018-07-05 09:12:45
【问题描述】:

我正在使用 Spring Data JPA,我想在我的存储库中编写一个 SQL 查询。

我有以下 SQL 查询(注意 LEFT JOIN):

SELECT * FROM institution LEFT JOIN 
(select * from building_institutions where building_institutions.building_id = 1) as reserved_institutions
ON reserved_institutions.institutions_user_id = institution.user_id
WHERE reserved_institutions.institutions_user_id is null;

我想在我的机构存储库中执行它,如下所示:

@Repository
public interface InstitutionRepository extends JpaRepository<Institution, Long>, PagingAndSortingRepository<Institution,Long> {
    // doesn't work
    //@Query("SELECT b.institutions as bi FROM Building b left join Institution i WHERE bi.building_id not in :id")
    Page<Institution> findPotentialInstitutionsByBuildingId(@Param("id") Collection<Long> id, Pageable pageable);

    // doesn't work    
    @Query(
            value = "SELECT * FROM kits_nwt.institution LEFT JOIN\n" +
                    "(SELECT * FROM kits_nwt.building_institutions WHERE kits_nwt.building_institutions.building_id = ?1) AS reserved_institutions\n" +
                    "ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id\n" +
                    "WHERE reserved_institutions.institutions_user_id IS null ORDER BY ?#{#pageable}",
            nativeQuery = true)
    Page<Institution> findPotentialInstitutionsByBuildingId(Long userId, Pageable pageable);
}

所以,我想用特定的 ID 获取所有不在建设中的机构(我将作为参数发送)。

这是我当前的数据库数据:

机构:

建设机构:

我想要什么:(在此查询中,id 设置为 1,用于演示目的)

我查看了许多 SO 问题和答案(例如 this one),但我无法找出解决方案。

那么,我该如何编写这个查询才能得到我想要的呢?

编辑 1:

@KevinAnderson 目前,我正在尝试:

@Query(
        value = "SELECT username, password, description, location, title, user_id FROM (institution INNER JOIN user ON institution.user_id = user.id) LEFT JOIN\n" +
                "(SELECT * FROM building_institutions WHERE building_institutions.building_id = 1) AS reserved_institutions\n" +
                "ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id\n" +
                "WHERE reserved_institutions.institutions_user_id IS null ORDER BY ?#{#pageable}",
        nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(Long userId, Pageable pageable);

我得到了这个例外:

MySQLSyntaxErrorException:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 2 行的 'WHERE) FROM building_institutions WHERE building_institutions.building_id = 1) A' 附近使用正确的语法

编辑 2:

@StanislavL 在这里:

问题是您的查询为我提供了 ID 为 25 的机构,因为它同时在 ID 为 1 的建筑物和 ID 为 2 的建筑物中。当您执行 JOIN 时,两个机构表中的机构 ID 均为 25 的 2 行和 building_institutions 表。然后,您的 WHERE 条件从这两行中删除一个,我得到一个 instituiton ID 为 25 的行,我不想要什么。

这是上面的图片:

编辑 3 - 由于以下原因,此问题不重复:

  • 我的查询是分页的(我在问题标题中添加了“分页”)
  • 我没有使用@NamedQuery,而是@Query
  • 我的错误是我没有将countQuery参数写入@Query注解

【问题讨论】:

  • 如果你想不出解决方案并不意味着它没有。
  • 你得到了什么结果?
  • @KevinAnderson 我会用我现在正在尝试的内容来编辑我的问题。
  • @RomanC 我没有说它没有。我希望它有一个,并且 SO 社区中的某个人知道它是什么并愿意帮助我。
  • @FilipSavic 不,如果不理解您问题中的问题,您不能说有人愿意帮助您。这不是帮助和支持。

标签: java mysql sql spring spring-data-jpa


【解决方案1】:

我解决了...

查询需要如下所示:

@Query(
        value = "SELECT * FROM \n" +
                "(institution INNER JOIN user ON institution.user_id = user.id) \n" +
                "LEFT JOIN \n" +
                "(SELECT * FROM \n" +
                "building_institutions \n" +
                "WHERE building_id = :userId)\n" +
                " AS reserved_institutions \n" +
                "ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id \n" +
                " where reserved_institutions.institutions_user_id IS null \n"
                + "ORDER BY ?#{#pageable}"
        ,
        countQuery = "SELECT count(*) FROM \n" +
                "(institution INNER JOIN user ON institution.user_id = user.id) \n" +
                "LEFT JOIN \n" +
                "(SELECT * FROM \n" +
                "building_institutions \n" +
                "WHERE building_id =:userId)\n" +
                " AS reserved_institutions \n" +
                "ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id \n" +
                "where reserved_institutions.institutions_user_id IS null \n" +
                "ORDER BY ?#{#pageable}",
        nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(@Param("userId") Long userId, Pageable pageable);

当我的查询看起来像这样时,我在 WHERE 附近的第 4 行收到错误:

@Query(
        value = "SELECT username, password, description, location, title, user_id FROM (institution INNER JOIN user ON institution.user_id = user.id) LEFT JOIN\n" +
                "(SELECT * FROM building_institutions WHERE building_institutions.building_id = 1) AS reserved_institutions\n" +
                "ON reserved_institutions.institutions_user_id = kits_nwt.institution.user_id\n" +
                "WHERE reserved_institutions.institutions_user_id IS null ORDER BY ?#{#pageable}",
        nativeQuery = true)
Page<Institution> findPotentialInstitutionsByBuildingId(Long userId, Pageable pageable);

那是因为我没有将countQuery 参数添加到@Query 注释中。

非常感谢所有试图提供帮助的人。

我希望我可以为其他人节省数小时的痛苦。

干杯! :)

【讨论】:

  • 哇,谢谢你救了我一天:)
  • 不客气 :)
  • 我为此苦苦挣扎了很长时间,但最终找到了您的答案!非常感谢!
  • 我的荣幸! :))
  • 这有帮助。非常感谢!
猜你喜欢
  • 2015-04-17
  • 1970-01-01
  • 2016-05-17
  • 1970-01-01
  • 2016-05-02
  • 2014-09-24
  • 2021-06-14
  • 2019-10-08
  • 1970-01-01
相关资源
最近更新 更多