3

假设我想找出父母和我父母在同一个班级的所有孩子。我可以这样写查询:

SELECT child.* FROM child
 JOIN parent ON child.ParentID = parent.ID
   WHERE parent.class IN (SELECT parent1.class 
     FROM parent1 JOIN child1
       ON parent1.id = child1.parentID
    WHERE child1.ID = MyID)

不知何故,这感觉好像我做错了,因为我(大约)写了两次相同的连接,但我想不出改进它的方法(我可以想出嵌套子查询的其他方法,但没有其中看起来更整洁)。

有没有我想念的干净的方法?或者我这样做对吗?

编辑:正如 GolzeTrol 在他对这个问题的(完整)回答中指出的那样,将孩子限制为只有一个父母是很奇怪的。他是完全正确的,我不打算在实际家庭上运行此查询,而是在其他一些表上运行此查询,其中每个孩子实际上只与一个父母相关联。

4

3 回答 3

2

我同意@GolezTrol 的解决方案,但您仍然可以按照自己的方式解决。要使查询按您编写的那样工作,您应该添加一个外部 WHERE 子句,将您自己排除在返回的子项之外(根据@GolezTroi 解决方案)。

此外,虽然它不会对执行产生任何影响,但使用 '=' 而不是 'IN' 样式的子查询在语义上更正确,因为您只希望您的子查询返回一条记录(即你父母所在的班级):

SELECT child.* FROM child
 JOIN parent ON child.ParentID = parent.ID
   WHERE parent.class = (SELECT parent1.class 
     FROM parent1 JOIN child1
       ON parent1.id = child1.parentID
    WHERE child1.ID = MyID)
   AND child.ID != MYID

当然,仍然存在您使用相关子查询的问题(即您已将子查询加入到外部查询中),并且与其他方法相比,这些查询往往需要更长的时间来处理。至于您关于两次执行相同连接的观点,SQL 通常会迫使您在更复杂的查询中执行此操作,特别是在您将记录与同一张表中的其他记录相关联的查询中。

于 2012-10-02T10:58:20.807 回答
2

加入他们吧。您必须加入两个表两次,以获取相关的父母,然后是他们的孩子,但除此之外,它是一个简单的内部联接。我添加了别名(在这种情况下你必须这样做)以明确每个表的“角色”是什么。

select
  otherkids.*
from
  child me
  /* Join below is weird. I got only 1 parent... */
  inner join parent myparents on myparents.ID = me.ParentID
  inner join parent otherparents on otherparents.class = myparents.class
  inner join child otherkids on otherkids.ParentID = otherparents.ID
where
  me.ID = :MyID and
  otherkids.ID <> me.ID /* Exclude myself */

我必须说我认为一个孩子有一个 ParentID 很奇怪,而我认为一个孩子有一个母亲和一个父亲,或者至少有两个父母。

家谱计划通常将孩子放在一个家庭中。所以一个家庭有配偶和孩子。这样,即使您不认识他们的父母(或只认识一个),您也可以连接孩子,并且如果他们离婚并再婚,您可以轻松地将他们连接到多个家庭。也可能是对您的表结构的建议。

于 2012-10-02T10:44:36.497 回答
-1

也许这可以解决你的问题

SELECT child.* FROM child INNER JOIN parent ON child.ParentID = parent.ID INNER JOIN parent2 ON parent.class = parent2.class INNER JOIN child2 ON child2.ParentID = parent.ID WHERE child.ID = myID and child2.ID < > 我的身份证

好吧试试这个:)

于 2012-10-02T10:49:01.773 回答