【问题标题】:Native Query to Select records to only contain specific ids用于选择记录以仅包含特定 ID 的本机查询
【发布时间】:2021-10-26 01:28:17
【问题描述】:

我正在我的应用程序中实施高级搜索。我对 Oracle 和 JPA 有点陌生。数据库结构与包含 StudentID 和 CourseID 的中间表具有多对多关系 (ERD)。

我正在尝试返回具有班级/课程列表的学生行。

基本上,我想要的结果

SELECT DISTINCT s.* FROM STUDENT s
INNER JOIN STUDENT_COURSE sc ON s.StudentID = sc.StudentID
INNER JOIN COURSE c ON c.CourseID = sc.CourseID
WHERE ( c.CourseID IN (SELECT DISTINCT CourseID FROM STUDENT_COURSE WHERE CourseID = 'A01') AND c.CourseID IN (SELECT DISTINCT CourseID FROM STUDENT_COURSE WHERE CourseID = 'A02'));

返回同时拥有“A01”和“A02”课程的学生的记录。

ID Age Grade
1 ... ...
4 ... ....
9 ... ....

有课程

Courses
A01,A02
A01,A02,A03,X02
A01, A02, A03

目标是使用 Spring Data JPA 获得类似的结果。并使选择任意数量的课程 ID 更加通用。

我试过了

@Query(value="SELECT DISTINCT s.* FROM STUDENT s "
+"INNER JOIN STUDENT_COURSE sc ON s.StudentID = sc.StudentID "
+"INNER JOIN COURSE c ON c.CourseID = sc.CourseID "
+"WHERE ( s.STUDENTID IN (SELECT DISTINCT STUDENTID FROM STUDENT_COURSE WHERE CourseID =:courseIds)",nativeQuery=true))
public List<Student> advancedSearch(@Param("courseIds") String courseIds);

一个例子, courseIds 字段包含“A01,A02”。结果将为空。

我查看了人们使用 IN 的示例。当我尝试它时,它会返回学生有课程AO1 OR A02 OR Both的记录。

不想要这个

ID Age Grade
2 ... ...
3 ... ....
8 ... ....

有课程

CourseID
A01,A03
A01, X01
A02

我想要同时具有 A01 AND A02 的学生记录,如另一表所示。

【问题讨论】:

  • 您发布的查询似乎没有返回您所说的结果。查询中没有任何内容将 courses 聚合为逗号分隔的字符串,并且两个 in 子句不会限制您所说的它们会限制的数据。
  • 我创建了一个字符串函数,该函数将从数组字段中收集课程编号并将其转换为逗号分隔的字符串。查询的结果将导致一个空的选定结果,不存在任何记录。
  • 这个“字符串函数”是您希望在查询中调用的 Oracle 中用户定义的聚合函数吗?还是您调用的 Java 函数并希望查询为每门课程返回一行(您的查询当前根本不返回任何课程信息)?而且你的in 子句没有意义——它们之间没有相关性,所以你想看看是否有学生上过特定的课程。
  • 如果您想要一个查询来返回所有参加过这两门课程的学生,我们当然可以提供帮助。当您所说的查询无法生成您想要的表格或您在问题文本中要求的结果时,很难提供帮助。
  • 这是一个 Java 函数。基本上,我希望查询返回学生根据第一个表参加了两门课程的记录。我想要一个更通用的查询,它可以包含多门课程(A01、A02、...)并返回参加过这两门课程的学生记录,而不是像 in 子句中的一门或另一门或两者都参加过的学生记录

标签: sql spring oracle jpa spring-data-jpa


【解决方案1】:

我的猜测是你想要的查询是

select s.name /* note this column doesn't appear in your ERD */
      ,s.age
      ,s.grade
  from student s
       join student_course sc
         on s.studentID = sc.studentID
 where sc.courseID IN ('A01', 'A02')
 group by s.name /* again, this column isn't in your ERD */
         ,s.age
         ,s.grade
having count(sc.courseID) = 2

这不会产生您想要的输出表。但是您发布的查询也没有。这将返回参加过这两门课程的所有学生(如果要更改数据模型以允许学生多次参加课程,则可以在 having 子句中添加 distinct)。它不会以逗号分隔列表的形式为您提供学生已参加的所有课程的列表。但是您发布的查询也没有返回任何课程信息。

如果这不是您想要的,那么更新您的问题会非常有帮助

  • 您的架构的 DDL 以文本形式(以便我们可以运行)而不是图像形式
  • 用于插入任何您想要的样本数据的 DML
  • 您希望查询返回的实际结果(因为您发布的查询返回的内容、您想要的数据表和您想要完成的描述性文本之间存在冲突,所以试图弄清楚哪个是正确的令人困惑)。

【讨论】:

  • 你实际上已经接近了,它得到了想要的结果。我想创建一个 JPA 查询,它可以获得更通用参数的结果,因此使用 :courseIds 可以组合多个课程 ID([Z01,Z02,A01,A02] 或 [C01,C04 ] 等)并返回具有课程 ID 组合的学生的记录。
  • @WattMonki - 因此您需要调整课程 ID 集以及返回学生所需的匹配数。我想传入一系列课程,而不是使用动态 SQL 来组装 SQL 语句,以避免每次都进行硬解析。
猜你喜欢
  • 2022-11-02
  • 2020-09-10
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 2021-05-16
  • 2017-10-22
相关资源
最近更新 更多