我记得在sql中连接表时,我被教导从不创建循环。 实际上,使用Business Objects,它甚至会告诉我在Universe中定义的模式中是否存在循环 我试图在网上搜索这个声明,但我找不到参考文献 为什么这样做很危险?
编辑:也许我太沉闷了。
我的问题不是关于用作“FOR LOOP”或类似的循环。 我在谈论SELECT语句中的这个WHERE子句:
WHERE TABLE1.foo = TABLE2.foo
AND TABLE2.bar = TABLE3.bar
AND TABLE3.baz = TABLE1.baz
如果绘制关系,您将在连接中看到“循环”。 从正确性和/或性能的角度来看,这是危险的吗? 谢谢大家。
编辑2:添加了一个示例。
我刚才想到了一个例子,也许这不是最好的,但我认为这有助于理解。
------------ ----------------- ----------------------
- DELIVERY - - DELIVERY_DATE - - DELIVERY_DETAILS -
------------ ----------------- ----------------------
- id - <--- - id - <----- date_id -
- company - |----- delivery_id - - product -
- year - - date - - quantity -
- number - ----------------- - datetime_of_event -
- customer - ----------------------
- ----------
1 <-----> N 1 <----> N
因此,每个表格的基数为1:N。
加入非常简单:
DELIVERY.id = DELIVERY_DATE.delivery_id AND
DELIVERY_DATE.id = DELIVERY_DETAILS.date_id
现在,假设我想加入另一个表,我在某个日期提供了一些其他信息。 我们来定义它:
------------
- EMPLOYEE -
------------
- company -
- year -
- number -
- date -
- employee -
------------
现在联接应该是:
DELIVERY.id = DELIVERY_DATE.delivery_id AND
EMPLOYEE.company = DELIVERY.company AND
EMPLOYEE.year = DELIVERY.year AND
EMPLOYEE.number = DELIVERY.number AND
EMPLOYEE.date = DELIVERY_DATE.date
总而言之,我将结束让EMPLOYEE同时加入DELIVERY和DELIVERY_DATE,并在合并中加入循环。
我应该以这种方式重写它吗?
EMPLOYEE.company = DELIVERY.company AND
EMPLOYEE.year = DELIVERY.year AND
EMPLOYEE.number = DELIVERY.number AND
EMPLOYEE.date IN (SELECT date FROM DELIVERY_DATE d WHERE d.delivery_id = DELIVERY.id)
编辑3:终于找到了一个链接
像往常一样,当你放弃搜索链接时,你会发现它 因此, this article 解释了所有内容。它与Business Objects有关,但内容是通用的 感谢您的所有时间。
答案 0 :(得分:2)
免责声明:这是一个非答案的答案,因为它既是答案,也是问题。它可能应该是一个评论,但你不能发表评论,除非你提出/回答问题,但由于我真的想要帮助,我会尽我所能,即使这不是事情在这里完成的方式。所以起诉我。
简短的回答是否定的,你不应该避免连接中的循环(或“循环”)。
更重要的是,构造查询以声明正确的逻辑条件以生成您正在寻找的数据。通常可以通过许多不同的方式建立相同的逻辑条件,因此有时候询问一种方式是否优于另一种方式是有意义的。当性能很重要时,这就变得特别重要。但首先,查询必须返回正确的结果集。如何实现这取决于底层架构。这就是你真正应该关注的内容。
在您的示例中,为什么EMPLOYEE在DELIVERY表中扮演角色?你为什么要加入这些专栏?这意味着员工与交货具有相同的“日期”是什么意思?我理解这是一个人为的例子,但我想说的是,连接是否在图中创建一个循环是完全(好的,主要)依赖于特定结果集的逻辑含义是。
在JOIN语法问题上,使用JOIN ... ON子句优于WHERE子句,因为它将您需要做的事情与数据过滤操作中的实体组合起来。
答案 1 :(得分:1)
嗯,你的问题很简单。您不应该使用where
子句来执行连接。您应该使用on
条款。您的联接可以表示为:
from Table1 join
Table2
on Table1.foo = Table2.foo join
Table3
on Table2.bar = Table3.bar and
Table1.baz = Table3.baz
这是否合适取决于您的数据结构。有时它是。你不应该担心它。
顺便说一下,我不会将此称为“循环”,它与编程中的“for循环”和SQL中的嵌套循环连接非常相关。您可以将此称为连接条件中的循环。
Wmax。 。 。至于新的连接语法。这不仅仅是品味问题。 from
子句中的“,”表示“交叉连接”。在大多数情况下,这是一项非常昂贵的操作。要明确你想要完成的事情要好得多:
FROM A cross join B
比其意图更清楚:
FROM A, B
其次,如果你离开“,”,你仍然有有效的语法:
FROM A B
但是,这意味着非常不同(将别名B分配给表A)。
第三个原因是最重要的原因。旧语法无法表达left outer join
,right outer join
和full outer join
。
因此,为了编写更清晰的查询,以避免错误,并访问更好的功能,您应该学习新的语法。