2008-10-20 117 views
79

交叉连接对两组元组执行笛卡尔乘积。交叉加入有什么用途?

SELECT * 
FROM Table1 
CROSS JOIN Table2 

哪种情况下渲染这样的SQL操作特别有用?

+19

这个问题已经关闭,真的很伤心。我认为它可能是社区Wiki的标志,但说这不是建设性的是不公平的。 – 2016-02-09 03:15:31

+0

我同意。这回答了我的确切问题。 – Hades 2017-08-04 15:08:59

回答

71

如果你有,你想要完全填充,如大小和颜色信息的衣服特定物品的“网格”:

select 
    size, 
    color 
from 
    sizes CROSS JOIN colors 

也许你想包含一排中的每一分钟的表某一天,你想用它来验证程序已经执行的每一分钟,所以你可能会跨越三个表:

select 
    hour, 
    minute 
from 
    hours CROSS JOIN minutes 

或者你有一组标准的报告规范的要应用到每月在这一年:

select 
    specId, 
    month 
from 
    reports CROSS JOIN months 

将这些视为视图的问题在于,在大多数情况下,您不需要完整的产品,特别是关于衣服。您可以将MINUS逻辑添加到查询中以删除某些不包含的组合,但可能会发现以其他方式填充表格并且不使用笛卡尔产品更容易。另外,您最终可能会尝试交叉连接表,这些表的行数可能比您想象的还要多,或者您的WHERE子句部分或完全缺失。在这种情况下,您的DBA会立即通知您这一遗漏。通常他或她不会高兴。

12

对于大多数数据库查询,您通常不需要完整的笛卡尔产品。关系数据库的全部功能是,您可以应用您可能感兴趣的任何限制,以避免从数据库中提取不必要的行。

我想一个人为的例子,你可能想那是,如果你有员工的表以及一个需要做的工作表,并希望看到一个员工都可以分配到一个工作。

7

生成测试数据。

1

想象一下,你有一个系列中,您要发出超过项目和日期(价格,可用性等)的特定组合查询。您可以将项目和日期加载到单独的临时表中并让您的查询交叉连接表格。这可能比枚举IN子句中的项目和日期的替代方法更为方便,特别是因为某些数据库限制了IN子句中元素的数量。

9

好吧,这可能不会回答这个问题,但是,如果这是真的(我甚至不能确定那),这是历史的一个有趣的一点。

在Oracle的早期阶段,其中一位开发人员意识到他需要复制表中的每一行(这可能是一个事件表,并且他需要将其更改为“开始事件”和“结束事件”) 。他意识到,如果他有一张只有两排的桌子,他可以做一个交叉连接,只选择前两列中的列,并得到他需要的。所以他创造了一张简单的桌子,他自然地称之为“DUAL”。

后来,他需要做一些事情,只能通过表格中的选择来完成,即使动作本身与表格无关(也许他忘记了他的手表并且想通过SELECT读取时间SYSDATE FROM ...)他意识到他仍然有他的DUAL桌子躺着,并用它。过了一会儿,他厌倦了看到两次打印的时间,所以他最终删除了其中一行。

Oracle的其他人开始使用他的表,最终决定将其包含在标准的Oracle安装中。

这就解释了为什么一个只有一行意义的表有一个名字,意思是“两个”。

3

采取类似于数字表的东西,它有10个数字0-9的行。您可以多次在该表上使用交叉连接,以获得需要多行的结果,并将结果进行适当编号。这有很多用途。例如,您可以将它与datadd()函数结合使用,以获取给定年份中每天的集合。

5

关键是“向我展示所有可能的组合”。我已经将这些与其他计算字段结合使用,然后对这些字段进行排序/过滤。

例如,假设您正在构建套利(交易)应用程序。您有卖家以一定的价格提供产品,并且买家要求产品付出代价。您对产品密钥进行交叉连接(以匹配潜在买家和卖家),计算成本和价格之间的差价,然后对desc进行排序。在此给你(中间人)最有利可图的交易执行。当然你几乎总是会有其他的边界过滤标准。