3

我有一个作业问题:

Find the celebs that have been in relationship with the same celeb. 
The result should be (celeb1, celeb2, celeb3) triples, 
meaning that celeb1 and celeb2 have been in relationship with celeb3.

现在“关系”表有 celeb1 和 celeb2 字段..其中值是 VARCHAR。

我对这个问题的解决方案是:

  CREATE VIEW Celeb1Rels AS
SELECT celeb1 AS c1, celeb2 AS c2 FROM relationships;

CREATE VIEW Celeb2Rels AS
SELECT celeb1 AS c2, celeb2 AS c3 FROM relationships;

SELECT * FROM Celeb1Rels NATURAL JOIN Celeb2Rels;

它工作正常。然而,教练发布了他的解决方案,他有:

SELECT X.celeb1, Y.celeb1, X.celeb2
FROM Relationships X, Relationships Y
WHERE X.celeb2=Y.celeb2 AND X.celeb1<Y.celeb1;

我不明白他为什么使用 X.celeb1 < Y.celeb1 它确实有效并给出了正确的输出,但我认为“<”用于比较数字?

谁能解释在这种情况下“<”在做什么?以及在比较 VARCHARS 时它的行为如何?

4

3 回答 3

3

这样你就不会得到重复的关系,例如 celeb1 和 celeb2 以及 celeb1 和 celeb3 之间的 2 个假设关系,你想要结果

celeb2, celeb3, celeb1

您需要第二个不等式运算符来确保表不会加入相同的关系(即 celeb1 和 Celeb2 加入回 celeb1 和 celeb2)。如果你要使用你的导师查询并修改它,而不是<使用不等于<>,你会得到结果:

celeb2, celeb3, celeb1
celeb3, celeb2, celeb1

但是这些行显示的内容相同,但顺序不同,>不等式运算符只是确保第二列始终是第一列之后按字母顺序排列的名称。

>因此,在应用于 varchars 时总结运算符按字母顺序工作,所以'a' < 'b''abc' > 'aaa'等等。

于 2013-02-13T13:20:35.833 回答
2

我想排除双倍的记录,例如:

如果(A,B)(B,C)在这个表中,那么如果查询没有AND X.celeb1<Y.celeb1我们得到

(A,B,C)(B,C,A)在输出中。加上这个条件,我们只输出一条(A,B,C)记录A < C

于 2013-02-13T13:20:13.593 回答
1

讲师的解决方案产生三元组,其中 CELEB2 处于两个关系中。WHERE 子句的这一部分...

X.celeb1<Y.celeb1

... 确保您只获得三个不同名人的行(即,它避免将相同的记录与自身匹配),并且每个三人组只能获得一行。

不如您想象的那样工作,它按字母顺序排序。也是如此'ANDY GARCIA' < 'ANDY KAUFMAN'

需要注意的事项:

  • 它使用 ASCII 值,因此区分大小写。这意味着'andy garcia' < 'ANDY KAUFMAN'是错误的。
  • 数字也按字母顺序排序,这'11' < '2'是真的。

“我不知道这个排序问题”

通过设置 NLS_SORT 参数,可以使 Oracle 排序大小写不敏感。但是,这不会改变比较;为此,我们需要将 NLS_COMP 参数更改为LINGUISTIC. 这些不是默认行为,仅仅是因为有太多代码可能依赖于区分大小写的排序。 了解更多

于 2013-02-13T13:19:27.210 回答