我正在使用 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 有一个属于 age=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());
我期待查询给我一个结果,其中条件可以匹配任何孩子。因为,过滤发生在父级。
任何帮助都会很棒。谢谢!
你可以这样做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
. 但这不是你想要的。
你想为这孩子行具有父IDSAGE = 7
和里面有一排TABLE2_CHILD
用House = 'Green'
。
您可以在两种情况下都使用 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
)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句