我需要 JPA/SQL 专家:内部连接的 EXISTS 查询 returns 错误结果
I need an JPA/SQL expert: EXISTS query on an Inner Join returns wrong result
我有三个 table 并且想要:
Select
所有同学from
第一个table,
在第二个 table
中至少与学区 '999' 的学校有一个联系
and
至少有一个与老师的联系 social_number '101'
and
至少给第三位编号为'103'的老师table。
table通过第二个table连接。
我创建了一个在线 sql 编译器来显示问题:
http://tpcg.io/FIoO79xi
这个查询工作正常,符合预期,直到我添加第三个 EXISTS
命令,我在其中搜索与老师 '103' 的连接。然后它不再是 return 学生 A,尽管他与老师 '103'
有联系
我通过在 Exists sub-query
中添加 joins
找到了解决方法:
http://tpcg.io/0sza7t5g
但是由于我的真实数据库 table 有数百万个条目,这将导致在 sub-query
经过的每一行中加入三个 table,如果只在 table 的末尾找到一个合适的条目。
我认为问题出在 sub-query
: WHERE th1.school_id = th.school_id
那里,我试图找到从第三位 table 老师到开头的连接 [= =61=]。如果我搜索与老师 102 而不是 103 的连接,则查询有效并且 return 的学生 A:
http://tpcg.io/2tHIEk3V
因为101老师和102老师有相同的school_id.
但是我怎样才能以不同的方式编写,以便在我搜索与老师 101 和 103 的联系时,查询也能找到学生 A?学生 A 与两者都有联系,因此应该有可能以某种方式存在...
添加:我不能使用三个单独的查询,然后对它们使用 Intersect
命令,因为我正在将 SQL
转换为 JPA
查询。 JPA
不知道相交...
为什么这么复杂?
`SELECT name
FROM student
LEFT JOIN school sc1 on student.student_id = sc1.student_id
LEFT JOIN teacher th1 on sc1.school_id = th1.school_id
WHERE sc1.district = '999'
AND th1.social_number in('101','103')`
不行吗?
第一个条件:
at least one connection to the school in district '999' in the second
table
需要 student
到 school
的连接。
第二和第三个条件:
at least one connection to the teacher with social_number '101'
and at least one to the teacher with number '103'
需要 student
到 school
和 teacher
:
的 2 单独 连接
SELECT s.name
FROM student s
INNER JOIN school sc on s.student_id = sc.student_id AND sc.district = 999
INNER JOIN school sc1 on s.student_id = sc1.student_id
INNER JOIN teacher t1 on t1.school_id = sc1.school_id AND t1.social_number = 101
INNER JOIN school sc2 on s.student_id = sc2.student_id
INNER JOIN teacher t2 on t2.school_id = sc2.school_id AND t2.social_number = 103
请注意,像 social_number in (101, 103)
这样的条件将不起作用,因为即使只满足其中一个条件,它也会产生 return 结果。
这就是为什么您需要 2 个连接 school
和 teacher
.
此外,所有连接都必须是 inner
,因为您要满足所有 3 个条件。
见 demo.
结果:
| name |
| ---- |
| A |
你需要 2 位老师table 加入
SELECT name
FROM student
left JOIN school sc1 on #student.student_id = sc1.student_id
left JOIN teacher th1 on sc1.school_id = th1.school_id and th1.social_number=101
left JOIN teacher th2 on sc1.school_id = th2.school_id and th1.social_number=103
where sc1.district=999
当我们在附加的 WHERE
子句中请求教师和学生之间的连接时,整个连接是不必要的。
Exists subquery
然后看起来像这样,而不是加入我使用额外的 where
来确保 teacher.school_id 与学生去的学校的 school.school_id 相同:
EXISTS (
SELECT *
FROM teacher th
WHERE th.social_number = '103'
AND th.school_id in (SELECT school_id FROM school WHERE student_id = student.student_id ))
我有三个 table 并且想要:
Select
所有同学from
第一个table,
在第二个 table
中至少与学区 '999' 的学校有一个联系and
至少有一个与老师的联系 social_number '101'
and
至少给第三位编号为'103'的老师table。
table通过第二个table连接。
我创建了一个在线 sql 编译器来显示问题: http://tpcg.io/FIoO79xi
这个查询工作正常,符合预期,直到我添加第三个 EXISTS
命令,我在其中搜索与老师 '103' 的连接。然后它不再是 return 学生 A,尽管他与老师 '103'
我通过在 Exists sub-query
中添加 joins
找到了解决方法:
http://tpcg.io/0sza7t5g
但是由于我的真实数据库 table 有数百万个条目,这将导致在 sub-query
经过的每一行中加入三个 table,如果只在 table 的末尾找到一个合适的条目。
我认为问题出在 sub-query
: WHERE th1.school_id = th.school_id
那里,我试图找到从第三位 table 老师到开头的连接 [= =61=]。如果我搜索与老师 102 而不是 103 的连接,则查询有效并且 return 的学生 A:
http://tpcg.io/2tHIEk3V
因为101老师和102老师有相同的school_id.
但是我怎样才能以不同的方式编写,以便在我搜索与老师 101 和 103 的联系时,查询也能找到学生 A?学生 A 与两者都有联系,因此应该有可能以某种方式存在...
添加:我不能使用三个单独的查询,然后对它们使用 Intersect
命令,因为我正在将 SQL
转换为 JPA
查询。 JPA
不知道相交...
为什么这么复杂?
`SELECT name
FROM student
LEFT JOIN school sc1 on student.student_id = sc1.student_id
LEFT JOIN teacher th1 on sc1.school_id = th1.school_id
WHERE sc1.district = '999'
AND th1.social_number in('101','103')`
不行吗?
第一个条件:
at least one connection to the school in district '999' in the second table
需要 student
到 school
的连接。
第二和第三个条件:
at least one connection to the teacher with social_number '101'
and at least one to the teacher with number '103'
需要 student
到 school
和 teacher
:
SELECT s.name
FROM student s
INNER JOIN school sc on s.student_id = sc.student_id AND sc.district = 999
INNER JOIN school sc1 on s.student_id = sc1.student_id
INNER JOIN teacher t1 on t1.school_id = sc1.school_id AND t1.social_number = 101
INNER JOIN school sc2 on s.student_id = sc2.student_id
INNER JOIN teacher t2 on t2.school_id = sc2.school_id AND t2.social_number = 103
请注意,像 social_number in (101, 103)
这样的条件将不起作用,因为即使只满足其中一个条件,它也会产生 return 结果。
这就是为什么您需要 2 个连接 school
和 teacher
.
此外,所有连接都必须是 inner
,因为您要满足所有 3 个条件。
见 demo.
结果:
| name |
| ---- |
| A |
你需要 2 位老师table 加入
SELECT name
FROM student
left JOIN school sc1 on #student.student_id = sc1.student_id
left JOIN teacher th1 on sc1.school_id = th1.school_id and th1.social_number=101
left JOIN teacher th2 on sc1.school_id = th2.school_id and th1.social_number=103
where sc1.district=999
当我们在附加的 WHERE
子句中请求教师和学生之间的连接时,整个连接是不必要的。
Exists subquery
然后看起来像这样,而不是加入我使用额外的 where
来确保 teacher.school_id 与学生去的学校的 school.school_id 相同:
EXISTS (
SELECT *
FROM teacher th
WHERE th.social_number = '103'
AND th.school_id in (SELECT school_id FROM school WHERE student_id = student.student_id ))