如何根据特定条件在同一个表中获取列的交集?

时间:2017-10-09 16:34:27

标签: sql oracle

假设我们有下表:

E1
+-------+------------+-----------+---------+
|  ID   | FIRST_NAME | LAST_NAME | SOME_ID |
+-------+------------+-----------+---------+
| GUID1 | John       | Smith     | O1      |
| GUID2 | John       | Smith     | O2      |
| GUID3 | Andrew     | Smith     | O3      |
| GUID4 | Sam        | Jackson   | O1      |
| GUID5 | John       | Jones     | O2      |
| GUID6 | Sam        | Jackson   | O2      |
+-------+------------+-----------+---------+

如果给出一个" SOME_ID"的列表值,我需要得到" FIRST_NAME"的交叉值。和" LAST_NAME"。

例如,如果" SOME_ID"是01和02.然后结果如下:

Result
+------------+-----------+
| FIRST_NAME | LAST_NAME |
+------------+-----------+
| John       | Smith     |
| Sam        | Jackson   |
+------------+-----------+

这是因为01和02都对应于具有" FIRST_NAME" John和" LAST_NAME"史密斯同样的逻辑适用于Sam Jackson的行。

到目前为止,我已经提出了以下问题:

(select first_name, last_name
from E1
where some_id = '01')
intersect
(select first_name, last_name
from E1
where some_id = '02');  

这确实给了我想要的结果,但是,似乎对于" SOME_ID"的每个新值都是新的查询。这似乎效率很低?

有更好的方法吗?也许通过加入?

我的另一个想法就是获得所有值的联合,并以编程方式获取内存中的交集。我可能是错的,但是如果没有比我上面提到的方式更好的方法,这似乎会更快。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

您可以使用group byhaving执行此操作。

select first_name, last_name
from E1
where some_id in ('01','02')
group by first_name, last_name
having count(distinct some_id) = 2

答案 1 :(得分:1)

以下是一种使用group by而不是join的方法:

select first_name, last_name
from e1
where some_id in ('01', '02')
group by first_name, last_name
having count(distinct some_id) = 2;

当您添加更多ID时,性能应该非常稳定(将" 2"更改为ID的数量)。