【问题标题】:Query on table joined with itself查询与自身连接的表
【发布时间】:2013-05-22 02:26:03
【问题描述】:

今天我有期末考试。我很高兴地批准了:D,但其中一个问题真的让我大吃一惊。

我需要帮助,所以我可以安息。

问题

我们有一个“人”表

(PK)id | name | fatherID
    ---------------------
    1  | gon  |   2
    2  | cesar|   6
    3  | luz  |   2
    4  | maria|   5
    5  | diego|   6
    6  | john |  -

这只是数据的一个例子。 该表与其自身有关系,在表 parentId(FK) 和表 id(PK) 上 我需要做一个查询,显示两列,一列是人名,另一列是他/她的表弟。

很简单,直到这里,对吧? 问题是我有一些限制

  • 仅允许使用 ANSI。没有 T-sql,或另一个。此外,ANSI 99 标准,而不是 2003 或更高版本
  • 不允许子查询。最糟糕的是:
  • 没有重复的关系。

例如,考虑到在这个例子中,gon 和 maria 是表亲。 如果我在结果中显示gon | maria,我将无法显示maria | gon

那么,我该怎么做呢? 真是让我头疼。

我尝试了什么?

嗯,最大的问题是最后一个必要条件,即数据的重复。忽略这一点,我把它放在我的考试中(知道错了..)

select p3.name as OnePerson, p4.name as Cousin
from
people p1
inner join people p2 on p1.fatherid = p2.fatherid and p1.id != p2.id
inner join people p3 on p1.id = p3.fatherid
inner join people p4 on p1.id = p4.fatherid

当然,这并不能解决最后一个要求,而且我的测试中有一个 4(我们以 4 通过),但无论如何,我的头在燃烧。所以,请帮助我!

探索的其他选择

我的一个朋友,也参加过同样的考试,说我

“好吧,考虑到每个关系都是重复的,我可以使用 top count(*) 和 order by 并得到正确的一半"

但是..Top 不是ANSI

【问题讨论】:

    标签: sql join self-join ansi-sql


    【解决方案1】:

    您可以在查询中添加WHERE p3.id < p4.id。这将消除像gon | mariamaria | gon 这样的重复结果。

    【讨论】:

      【解决方案2】:
      SELECT T1.id , T2.id FROM 
      (
          SELECT A.id,A.fid FROM family A 
          WHERE a.fid IN 
          ( 
              SELECT id FROM family
              WHERE fid IN (SELECT id FROM family WHERE fid IS NULL)
          )
      )T1
      
      JOIN
      (
           SELECT A.id,A.fid FROM family A 
           WHERE a.fid IN 
           ( 
                SELECT id FROM family
                WHERE fid IN (SELECT id FROM family WHERE fid IS NULL)
           )
      )T2
      ON t1.fid<>t2.fid
      AND t1.id<t2.id
      

      【讨论】:

        【解决方案3】:

        这将为您提供所需格式的结果。

        SELECT TAB1.ID,TAB2.ID
        FROM 
        (
        SELECT * FROM people T1
         WHERE fatherID IN ( SEL T1.ID FROM people T1 INNER JOIN  people T2 
        ON(     T1.id=T2.fatherID) WHERE T1.fatherID IS NOT NULL GROUP BY 1) ) TAB1
        
        INNER JOIN 
        (
        SELECT * FROM people T1
        WHERE fatherID IN ( SEL T1.ID FROM people T1 INNER JOIN  people T2 
        ON(   T1.id=T2.fatherID)WHERE T1.fatherID IS NOT NULL GROUP BY 1) ) TAB2
        
        ON( TAB1.fatherID<>TAB2.fatherID)
        GROUP BY 1,2
        WHERE TAB1.ID <TAB2.ID;   
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-12
          • 2021-10-03
          • 1970-01-01
          相关资源
          最近更新 更多