SQL 查询 JOIN 或 IN 运算符?

SQL Query JOIN or IN operator?

我有两张桌子, 个人朋友。 FRIENDS 有字段 NAME 和 SURNAME。

一个人有N个朋友

我想检索所有至少有两个朋友的人,一个名字="mark",另一个名字="rocco",姓氏="siffredi".

示例:如果我有一个人有 5 个朋友,其中一个叫 mark,没有一个叫 rocco siffredi,则不会返回任何表格。

我在想:

SELECT * FROM person p
         JOIN friends AS f ON p.ID=f.personID
WHERE f.name ="mark" AND f IN 
            ( SELECT * from FRIENDS WHERE name="rocco" and surname="siffredi")

SELECT * FROM person p
         JOIN friends AS f1 ON p.ID=f1.personID
         JOIN friends AS f2 ON p.ID=f2.personID
WHERE    f1.name="mark" AND f2.name="rocco" AND f2.surname="siffredi"

最好的方法是什么?我的意思是执行它的最快方法。 我不关心可读性。 还有其他方法可以执行此查询吗? Ty.

编辑:在 ID 上添加了连接...

您的架构设计对于您尝试做的事情来说不是很好...我会像您一样有一个 Person table,它还会包含一个名为 PersonId 的唯一标识符。然后我会有一个 Friends table,它有两个字段 - Person1Id 和 Person2Id。

这为您提供了几个重要的优势 - 首先,您的系统能够处理多个名为 John Smith 的人(因为我们加入 ID 而不是姓名...)。其次,一个人的详细信息只记录在Persontable中。真理的一个定义...

我不得不猜测你的列名并组成 table:

使用 EXISTS:

CREATE table FRIENDS(person_id INT, friend_id INT)

go

SELECT * 
FROM person 
WHERE 
  EXISTS
   (SELECT * 
    FROM friends f 
    JOIN person per
    ON f.friend_id = per.id
    WHERE
      per.name ='mark' AND
      person.id = f.person_id) AND
  EXISTS
   (SELECT * 
    FROM friends f 
    JOIN person per
    ON f.friend_id = per.id
    WHERE
      per.name = 'rocco' AND
      per.surname='siffredi' AND
      person.id = f.person_id)

将这些数据作为输入:

INSERT INTO Person VALUES 
(1, 'Bob', 'Smith'),
(2, 'Jim', 'Jones')

INSERT INTO Friends VALUES
(1, 1, 'Mark', 'Tally'),
(2, 1, 'John', 'Smith'),
(3, 1, 'Jack', 'Pollock'),
(4, 2, 'Mark', 'Rush'),
(5, 2, 'Rocco', 'Siffredi'),
(6, 2, 'Mark', 'Bush')

您可以使用此查询:

SELECT PersonId, COUNT(*) AS NoOfFriends
FROM (
   SELECT DISTINCT PersonId, Name,
          Surname = CASE WHEN NAME = 'Mark' THEN NULl
                         ELSE Surname
                    END  
   FROM Friends
   WHERE Name = 'Mark' OR (Name = 'Rocco' AND Surname = 'Siffredi') ) t
GROUP BY PersonId

获得每个 PersonID 所需好友的不同数量:

PersonId    NoOfFriends
------------------------
1           1
2           2

您现在可以在 PersonId 上加入上面的 table 表达式并按 NoOfFriends:

过滤它
SELECT p.*
FROM Person AS p
INNER JOIN (
   SELECT PersonId, COUNT(*) AS NoOfFriends
   FROM (
      SELECT DISTINCT PersonId, Name,
             Surname = CASE WHEN NAME = 'Mark' THEN NULl
                         ELSE Surname
                       END  
      FROM Friends
      WHERE Name = 'Mark' OR (Name = 'Rocco' AND Surname = 'Siffredi') ) t
   GROUP BY PersonId ) s ON s.PersonId = p.ID 
WHERE s.NoOfFriends = 2

以便仅获得具有所需关联朋友组合的人:

ID  Name    Surname
-------------------
2   Jim     Jones

P.S。在@t-clausen.dk 发表评论后,我已经完全重写了我的答案。