我正在使用Oracle 11g,并且具有具有如下数据和结构的表:
TABLE1_PARENT:
-------------------
PID | Name | Age |
-------------------
1 | Mark | 35 |
2 | Jane | 40 |
3 | Agatha | 45 |
-------------------
TABLE2_CHILD
==============================================
CID | Name | Age | Class | House | PID |
----------------------------------------------
1 | John | 7 | 3 | Red | 1 |
2 | Marie | 5 | 1 | Yellow| 2 |
3 | Petra | 6 | 2 | Green | 3 |
4 | Taylor | 8 | 4 | Blue | 2 |
5 | Lean | 9 | 5 | Red | 2 |
6 | Justin | 7 | 3 | Yellow| 3 |
7 | Arianna | 5 | 1 | Blue | 3 |
8 | Brendon | 6 | 2 | Green | 3 |
9 | Shawn | 7 | 3 | Red | 1 |
----------------------------------------------
对于单个条件,查询很简单:
SELECT * FROM TABLE1_PARENT WHERE PID IN (SELECT PID FROM TABLE2_CHILD WHERE AGE=7);
这将导致以下结果:
TABLE1_PARENT:
-------------------
PID | Name | Age |
-------------------
1 | Mark | 35 |
3 | Agatha | 45 |
-------------------
但是,如果我要获取孩子的年龄为7岁并属于house ='GREEN'的父母的清单,请编写以下查询:
SELECT * FROM TABLE1_PARENT WHERE PID IN (SELECT PID FROM TABLE2_CHILD WHERE AGE=7 AND house='GREEN');
我没有结果。
我希望结果是:
TABLE1_PARENT:
-------------------
PID | Name | Age |
-------------------
3 | Agatha | 45 |
-------------------
因为阿加莎(Agatha)有一个孩子,年龄为7岁,一个孩子为house ='GREEN'。
我能够为使用Java流的类似数据结构提供解决方案。我正在尝试使用Oracle SQL做同样的事情。
List<Parent> filteredParents = parents.stream()
.filter(parent -> parent.getChildren().stream()
.anyMatch(child -> child.getAge().equals("7")) && parent.getChildren().stream()
.anyMatch(child -> child.getHouse().equalsIgnoreCase("Green")))
.collect(Collectors.toList());
我希望查询给我一个结果,条件可以匹配任何孩子。因为,过滤是在父级进行的。
任何帮助都会很棒。谢谢!
答案 0 :(得分:1)
您可以使用EXISTS
来做到这一点:
SELECT t.*
FROM TABLE1_PARENT t
WHERE t.PID IN (
SELECT PID FROM TABLE2_CHILD WHERE AGE=7
) AND EXISTS (
SELECT 1 FROM TABLE2_CHILD WHERE PID = t.PID AND House = 'Green'
)
查询的问题是它试图在TABLE2_CHILD
内同一行中同时应用这两个条件。但这不是您想要的。
您需要为其子行具有AGE = 7
且在TABLE2_CHILD
内有House = 'Green'
的行的父ID。
您可以对两种情况都使用EXISTS,这样可能会更有效:
SELECT t.*
FROM TABLE1_PARENT t
WHERE EXISTS (
SELECT 1 FROM TABLE2_CHILD WHERE PID = t.PID AND AGE=7
) AND EXISTS (
SELECT 1 FROM TABLE2_CHILD WHERE PID = t.PID AND House = 'Green'
)
或通过将子表按PID
分组进行条件聚合:
SELECT * FROM TABLE1_PARENT
WHERE PID IN (
SELECT PID
FROM TABLE2_CHILD
GROUP BY PID
HAVING
SUM(CASE WHEN Age = 7 THEN 1 ELSE 0 END) > 0
AND
SUM(CASE WHEN House = 'Green' THEN 1 ELSE 0 END) > 0
)
答案 1 :(得分:1)
您没有得到输出,因为在TABLE2_CHILD中,温室中没有7岁的孩子。为了获得预期的结果,查询应为:
SELECT *从TABLE1_PARENT的PID IN(从TABLE2_CHILD的SELECT PID到AGE = 7)和PID IN(从TABLE2_CHILD的PID在TABLE2_CHILD的house ='GREEN');
答案 2 :(得分:0)
如果要获得一个孩子的父母,该孩子的年龄为7岁,并且同一个孩子属于house = GREEN,请使用您已经编写的查询:
SELECT * FROM TABLE1_PARENT WHERE PID IN (SELECT PID FROM TABLE2_CHILD IF AGE=7 AND house='GREEN');
如果要让孩子年龄为7岁或房子为GREEN或两者兼有的父母,请使用
SELECT * FROM TABLE1_PARENT WHERE PID IN (SELECT PID FROM TABLE2_CHILD IF AGE=7 OR house='GREEN');