【发布时间】: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