【问题标题】:Remove Duplicates From JOIN从 JOIN 中删除重复项
【发布时间】:2014-06-15 12:25:27
【问题描述】:

我目前正在学校学习数据库,但不幸的是,我们的老师根本不喜欢帮助或回答问题。我目前正在做一些 Oracle DB 练习,但遇到了一个我真的不知道如何解决的问题。

表 1:学生

   ID      FAMILY NAME     FIRST NAME    BIRTH DATE      IM_DATE    FACULTY

  4711    Lehmann          Heini         13.03.89       01.09.08     I         
  4712    Huber            Sven          14.07.89       01.09.08     IWI       
  4713    Meier            Swantje       11.04.88       01.03.09     IWI       
  4714    Tunix            Ole           15.03.88       01.03.09     IWI       
  4715    Kannix           Peter         02.11.89       01.03.09     IWI       
  4716    Weissnix         Axel          15.12.88       01.03.09     IWI     

表 2:LN

   ID    FKBEZ         VNR P_DATE        GRADE

  4711   DB1            1 02.02.08        4,7 
  4711   DB1            2 07.07.09          5 
  4711   PR1            1 28.01.09          3 
  4712   DB1            1 02.02.08        3,7 
  4713   DB1            1 02.02.08        1,7 
  4713   DB2            1 02.02.09        3,7 
  4714   PR1            1 28.01.09          2 
  4715   DB1            1 02.02.08          5 
  4711   DB2            1 14.07.09        1,3 
  4711   PR2            1 30.06.09        2,3 

现在,问题来了。

Q1:创建一个会导致重复行的 SQL 查询 (JOIN)。 Q2:从 Q1 更改您的查询,现在它不会显示任何重复项。

我的第一个“问题”是我不能 100% 确定重复的定义是什么。即使您没有在 SELECT 命令中选择它们,是否会在所有列上重复具有 100% 相同内容的行?

示例: 假设我创建了一个查询,并在 SELECT 命令中选择了“姓氏”和“年龄”列,我的结果如下所示:

Family Name          Age

Miller               20
Miller               20

但这实际上是两个不同的人,名字也不同。这些是否有资格作为重复项,因为我没有选择名字,因此它没有显示,或者我通过 SELECT 选择的内容无关紧要,并且重复行只有在它们 100% 相同时才有资格作为重复项?

好的,回到我的问题。 对于 Q1,我选择了一个简单的 (INNER) JOIN 查询,如下所示

选择 S.ID、S.Family_Name、S.First_Name、LN.FKBEZ 来自学生 S 加入LN ON S.ID = LN.ID

FAMILY NAME               FIRST NAME               FKBEZ       (GRADE)

Lehmann                   Heini                     DB1          4,7 
Lehmann                   Heini                     DB1            5 
Lehmann                   Heini                     PR1            3 
Huber                     Sven                      DB1          3,7 
Meier                     Swantje                   DB1          1,7 
Meier                     Swantje                   DB2          3,7 
Tunix                     Ole                       PR1            2 
Kannix                    Peter                     DB1            5 
Lehmann                   Heini                     DB2          1,3 
Lehmann                   Heini                     PR2          2,3 

这就是结果。我没有在我的查询中选择“等级”,但我也为你列出了它,所以你可以更好地理解我的问题。 现在,由于我没有在查询中选择“GRADE”,我认为第 1 + 2 行是重复的,因为它们在每个 visible 列中都是相同的。然后我继续到 Q2 并使用完全相同的查询,只是这次使用了 NATURAL JOIN(因为这将消除所有重复的行),但结果完全相同。

所以现在我的结论是,只有在每个 visible'invisible' 列上 100% 相同的行才被视为重复行。 但现在我实际上完全被难住了,因为我不知道如何解决 Q1 + Q2。

重要的是要知道,我们不应该使用 DISTINCT 或 GROUP BY 来解决这些问题。只有(不同种类的)JOINS、INTERSECT、UNION 和 MINUS。

我想你可以看到我在撰写这篇文章时投入了很多时间和精力,所以如果你们能帮助我完成这篇文章,我将不胜感激。

谢谢。

【问题讨论】:

  • 根据你在提问时所表现出的理解,我不太确定这门课是否会对你有所帮助。
  • 我认为您需要向您的讲师提出一些澄清。您至少可以向他询问您的第一个“答案”,您只是在其中包含/排除列,或者可能将列添加到连接中。您是否必须保留非重复行? UNION 将为您执行 DISTINCT,所以这有点作弊。您可以在不显式添加GROUP BY 子句(也作弊)的情况下获得最大/最小值。 INTERSECT/MINUS 在集合上工作,因此将有助于保留/删除 all 行,除非您先对它们进行重复数据删除。 NATURAL JOIN = JOIN 有条件,差不多。
  • ...我是个白痴,我忘了有一种方法可以使用LEFT JOINs 来做到这一点(适用于任何 RDBMS)。在 SO 上查找如何查找/删除重复项或在 [greatest-n-per-group] 中查找。不过,这并不直观,因此人们通常需要向他们指出。

标签: sql inner-join outer-join cross-join natural-join


【解决方案1】:

尝试使用左连接。第二个表中没有相应的记录将具有空值。埃斯。 Select * from t1,t2 where t1 left join t2. t2 上的非匹配值将为空

【讨论】:

  • 你正在混合连接样式,要么做... from t1 left join t2 on ...要么... from t1, t2 where ...
  • 。对不起,这是“习惯”。 select * from t1 join t2 on t1.column =t2.column.
  • LEFT JOININNER JOIN,无论如何,他的问题并不在于加入的类型......
猜你喜欢
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 2020-02-27
  • 2012-07-24
  • 2018-06-28
  • 2019-02-03
  • 1970-01-01
  • 2019-01-18
相关资源
最近更新 更多