成对子查询不能按预期工作

时间:2018-08-17 15:43:40

标签: sql oracle

我有3张桌子,高中生,朋友和喜欢的人。这些表的数据如下所示:

Highschooler
ID  name    grade
1510    Jordan  9
1689    Gabriel 9
1381    Tiffany 9
1709    Cassandra   9
1101    Haley   10
1782    Andrew  10
1468    Kris    10
1641    Brittany    10
1247    Alexis  11
1316    Austin  11
1911    Gabriel 11
1501    Jessica 11
1304    Jordan  12
1025    John    12
1934    Kyle    12
1661    Logan   12

Friend
ID1 ID2
1510    1381
1510    1689
1689    1709
1381    1247
1709    1247
1689    1782
1782    1468
1782    1316
1782    1304
1468    1101
1468    1641
1101    1641
1247    1911
1247    1501
1911    1501
1501    1934
1316    1934
1934    1304
1304    1661
1661    1025
1381    1510
1689    1510
1709    1689
1247    1381
1247    1709
1782    1689
1468    1782
1316    1782
1304    1782
1101    1468
1641    1468
1641    1101
1911    1247
1501    1247
1501    1911
1934    1501
1934    1316
1304    1934
1661    1304
1025    1661

Likes
ID1 ID2
1689    1709
1709    1689
1782    1709
1911    1247
1247    1468
1641    1468
1316    1304
1501    1934
1934    1501
1025    1101

我执行以下查询,该查询利用了成对子查询:

select a.name, b.name
from highschooler a join highschooler b
on a.id< b.id
where (a.id, b.id) in (
select id1, id2
from likes);

此查询返回以下信息:

NAME                      NAME
------------------------- -------------------------
Gabriel                   Cassandra
John                      Haley
Alexis                    Kris
Jessica                   Kyle

我执行另一个查询:

select a.name, b.name
from highschooler a join highschooler b
on a.id<b.id
where (a.id, b.id) in (
select id2, id1
from likes);

哪个返回以下信息:

NAME                      NAME
------------------------- -------------------------
Gabriel                   Cassandra
Cassandra                 Andrew
Kris                      Brittany
Jordan                    Austin
Alexis                    Gabriel
Jessica                   Kyle

这可以按预期工作,但是以下查询导致奇怪:

SQL> select a.name, b.name
  2  from highschooler a join highschooler b
  3  on a.id < b.id
  4  where (a.id, b.id) in (
  5  select id1, id2
  6  from likes)
  7  and (a.id, b.id) in (
  8  select id2, id1
  9  from likes);

NAME                      NAME
------------------------- -------------------------
Gabriel                   Cassandra
John                      Haley
Alexis                    Kris
Jessica                   Kyle

从理论上讲,此查询应仅返回加布里埃尔·卡桑德拉(Gabriel-Cassandra)和杰西卡·凯尔(Jessica-Kyle)对。为什么不返回此结果?

1 个答案:

答案 0 :(得分:1)

确实仅返回这两对。

with Highschooler (id, name) as (
SELECT 1510,    'Jordan'  FROM DUAL UNION ALL
SELECT 1689,    'Gabriel' FROM DUAL UNION ALL
SELECT 1381,    'Tiffany' FROM DUAL UNION ALL
SELECT 1709,    'Cassandra'   FROM DUAL UNION ALL
SELECT 1101,    'Haley'   FROM DUAL UNION ALL
SELECT 1782,    'Andrew'  FROM DUAL UNION ALL
SELECT 1468,    'Kris'    FROM DUAL UNION ALL
SELECT 1641,    'Brittany' FROM DUAL UNION ALL
SELECT 1247,    'Alexis'  FROM DUAL UNION ALL
SELECT 1316,    'Austin'  FROM DUAL UNION ALL
SELECT 1911,    'Gabriel' FROM DUAL UNION ALL
SELECT 1501,    'Jessica' FROM DUAL UNION ALL
SELECT 1304,    'Jordan'  FROM DUAL UNION ALL
SELECT 1025,    'John'    FROM DUAL UNION ALL
SELECT 1934,    'Kyle'    FROM DUAL UNION ALL
SELECT 1661,    'Logan'   FROM DUAL ),
Likes ( id1, id2 ) AS (
SELECT 1689,    1709 FROM DUAL UNION ALL
SELECT 1709,    1689  FROM DUAL UNION ALL
SELECT 1782,    1709  FROM DUAL UNION ALL
SELECT 1911,    1247 FROM DUAL UNION ALL
SELECT 1247,    1468 FROM DUAL UNION ALL
SELECT 1641,    1468 FROM DUAL UNION ALL
SELECT 1316,    1304 FROM DUAL UNION ALL
SELECT 1501,    1934 FROM DUAL UNION ALL
SELECT 1934,    1501 FROM DUAL UNION ALL
SELECT 1025,    1101 FROM DUAL)
SELECT
    a.name,
    b.name
FROM
    highschooler a
    JOIN highschooler b
    ON a.id < b.id
WHERE
    ( a.id,
    b.id ) IN (
        SELECT
            id1,
            id2
        FROM
            likes
    )
    AND   ( a.id,
    b.id ) IN (
        SELECT
            id2,
            id1
        FROM
            likes
    );

结果:

+---------+-----------+
|  NAME   |  NAME_1   |
+---------+-----------+
| Gabriel | Cassandra |
| Jessica | Kyle      |
+---------+-----------+