【问题标题】:SQL - Avoiding duplicate pairs on a self join/inner join?SQL - 避免自联接/内联接上的重复对?
【发布时间】:2019-01-20 05:47:54
【问题描述】:

我有数据库,在其他表中我有这个:

CREATE TABLE `Physiotherapist`(
`pid` INT,
`name` VARCHAR(40),
`hours` INT,
`cid` INT    

我想编写一个 SQL 查询,该查询返回在同一诊所工作的一对物理治疗师的列表,但会 不返回重复项。到目前为止,我的回答是:

SELECT  p1.name AS name1, p2.name AS name2
FROM    Physiotherapist p1 
INNER JOIN Physiotherapist p2 on p2.cid = p1.cid AND p1.name != p2.name

或使用自连接的替代解决方案:

SELECT  p1.name, p2.name
FROM    Physiotherapist p1, Physiotherapist p2
WHERE   p1.cid = p2.cid AND p1.name !=(SELECT p2.name)

无论如何我都会得到这个结果:

name1:            name2:

Jan Christensen   Ira Assent
Ira Assent        Jan Christensen

即同一对。我只想要一个副本,因为它们显示相同的信息,但我想不出一种方便的方法来做到这一点。

编辑:带有示例数据的完整数据库代码

DROP TABLE IF EXISTS Physiotherapist;

CREATE TABLE `Physiotherapist`(
    `pid` INT,
    `name` VARCHAR(40),
    `hours` INT,
    `cid` INT
);

INSERT INTO Physiotherapist VALUES('123','Ira Assent','8','1');
INSERT INTO Physiotherapist VALUES('246','Annika Schmidt','1','2');
INSERT INTO Physiotherapist VALUES('327','Jan Christensen','5','1');
INSERT INTO Physiotherapist(`pid`,`name`) VALUES('455','Simon Winter');

DROP TABLE IF EXISTS Clinic;

CREATE TABLE `Clinic`(
    `cid` INT,
    `name` VARCHAR(40),
    `address` VARCHAR(40)
);

INSERT INTO Clinic VALUES ('1','PhysCentral','Aarhus C');
INSERT INTO Clinic VALUES ('2','PhysIOgnomy','Aarhus N');
INSERT INTO Clinic VALUES ('3','Physios','Aarhus V');

DROP TABLE IF EXISTS Appointment;

CREATE TABLE `Appointment`(
    `aid` INT,
    `date` DATE,
    `time` INT,
    `pid` INT
);

INSERT INTO Appointment VALUES(34716,'2018-06-12','10','246');
INSERT INTO Appointment VALUES(23118,'2018-08-18','11','327');
INSERT INTO Appointment VALUES(88223,'2018-10-03','9','246');

【问题讨论】:

  • 添加更多示例表数据,以及新的预期结果。
  • 样本数据和预期输出有助于指导
  • 我添加了包含所有示例数据的完整表格
  • 您的预期结果是什么?
  • 要么 (Jan Christensen - Ira Assent) 要么 (Ira Assent - Jan Christensen),但不能同时使用。如前所述,我想编写一个 SQL 查询,该查询返回在同一诊所工作但不会返回重复的物理治疗师对的列表。

标签: sql join duplicates self


【解决方案1】:
SELECT  DISTINCT p1.name, p2.name
FROM    Physiotherapist p1 INNER JOIN Physiotherapist p2
ON  p1.cid = p2.cid AND p1.pid>p2.pid

这里我们使用诊所 ID 进行自连接以获取对,在 where 条件下进行 pid 比较避免重复值/对,然后最后我们执行 distinct 以仅获取不同的对。

【讨论】:

    【解决方案2】:

    只是为了给你一个想法,我有一个包含 authorid 和 bookid 字段的出版物表。要获得至少在一本书中是共同作者的作者,我的 sql 查询是:

    SELECT p1.authorid , p2.authorid
    FROM publications p1 , publications p2
    WHERE p1.bookid = p2.bookid AND p1.authorid<>p2.authorid AND p1.authorid>p2.authorid;
    

    希望你明白

    【讨论】:

      【解决方案3】:

      我认为下面的查询对你有用

      select T3.* from 
      (select clname,count( distinct pname) from
      (SELECT  p1.name as pname,c.name as clname
      FROM    Physiotherapist p1 inner join
       Clinic c on p1.cid=c.cid
       ) as T  GROUP BY clname
       having count( distinct pname)>1
      ) T2 inner join        
      
       (SELECT  p1.name as pname,c.name as clname
      FROM    Physiotherapist p1 inner join
       Clinic c on p1.cid=c.cid
        ) t3 on t2.clname=t3.clname
      

      http://sqlfiddle.com/#!9/1cbace/10

      【讨论】:

      • 好吧,虽然这似乎不会产生重复,即使我广告更多的治疗师,我正在处理的问题要求我“编写一个 SQL 查询,返回在同一家诊所。不要返回重复。”。 IE。我需要他们配对。但是漂亮的作品,非常感谢!
      【解决方案4】:

      试试

      SELECT  p1.name, p2.name
      FROM    Physiotherapist p1, Physiotherapist p2
      WHERE   p1.cid = p2.cid AND p1.name !=(SELECT p2.name) AND p1.pid > p2.pid
      

      这样你应该只能从两种可能的组合中得到一种。

      【讨论】:

      • 它产生 (Jan Christensen - Ira Assent) 作为结果。虽然它确实产生了我想要的东西,但我想知道它是否正确答案。不过非常感谢!
      • 添加更多治疗师表明它不起作用,但还是谢谢
      【解决方案5】:

      也只需包含 pid pid(假设这是主键,从您的定义来看确实如此);

      SELECT  p1.name AS name1, p2.name AS name2
      FROM    Physiotherapist p1 
      INNER JOIN Physiotherapist p2 
          on p2.cid = p1.cid 
          AND p1.name != p2.name 
          -- Add this to WHERE
          AND p1.pid != p2.pid
      

      【讨论】:

      • 它似乎仍然在相反的列中产生重复的对。很难,我显然不需要检查等效名称。我很感谢你的回答,谢谢。
      猜你喜欢
      • 1970-01-01
      • 2016-03-06
      • 2016-12-25
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 2017-11-03
      • 2016-09-23
      • 1970-01-01
      相关资源
      最近更新 更多