交叉连接的用途是什么?

交叉连接对这两个集合的元组执行笛卡儿积。

SELECT *
FROM Table1
CROSS JOIN Table2

哪些情况使得这样的 SQL 操作特别有用?

71468 次浏览

对于大多数数据库查询,你通常不会想要一个完整的笛卡儿积。关系数据库的强大之处在于,您可以应用您可能感兴趣的任何限制,以避免从数据库中提取不必要的行。

I suppose one contrived example where you might want that is if you have a table of employees and a table of jobs that need doing and want to see all possible assignments of one employee to one job.

为测试生成数据。

如果你有一个你想完全填充的“网格”,比如某件衣服的尺寸和颜色信息:

select
size,
color
from
sizes CROSS JOIN colors

Maybe you want a table that contains a row for every minute in the day, and you want to use it to verify that a procedure has executed each minute, so you might cross three tables:

select
hour,
minute
from
hours CROSS JOIN minutes

或者你有一套标准的报告规格,你想申请每个月在一年中:

select
specId,
month
from
reports CROSS JOIN months

维护这些视图的问题在于,在大多数情况下,您不想要一个完整的产品,特别是关于服装的产品。你可以在查询中添加 MINUS逻辑来删除某些你没有的组合,但是你可能会发现用其他方式填充一个表而不使用笛卡儿积会更容易。

另外,您可能最终会尝试在比您想象的多几行的表上进行交叉连接,或者您的 WHERE子句可能部分或完全丢失。在这种情况下,您的 DBA 将立即通知您有关遗漏。通常他或她会不高兴。

Imagine you had a series of queries you want to issue over a specific combination of items and dates (prices, availability, etc..). You could load the items and dates into separate temp tables and have your queries cross join the tables. This may be more convenient than the alternative of enumerating the items and dates in IN clauses, especially since some databases limit the number of elements in an IN clause.

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

在 Oracle 的早期,一个开发人员意识到他需要复制表中的每一行(例如,有可能是一个事件表,他需要改变它单独的“开始事件”和“结束事件”条目)。他意识到,如果有一个只有两行的表,他可以进行交叉连接,只选择第一个表中的列,并得到他所需要的信息。因此,他创建了一个简单的表,他自然而然地称之为“ DUAL”。

后来,他需要做一些事情,只能通过选择从一个表,即使动作本身与表无关,(也许他忘了他的手表,想要读取时间通过选择 SYSDATE FROM...)他意识到他仍然有他的双表躺在周围,并使用。过了一会儿,他厌倦了看到时间印刷两次,所以他最终删除了其中一行。

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

Which explains why a table whose only significance is that it has one row has a name which means "two".

取一个类似于数字表的东西,它有10行的数字0-9。您可以在该表上多次使用 cross join 来获取结果,该结果具有您需要的任意多行,并且结果的编号适当。这有很多用途。例如,您可以将它与 datadd ()函数组合起来,以获得给定年份中每一天的集合。

关键是“告诉我所有可能的组合”。我将它们与其他计算字段结合使用,然后对这些字段进行排序/筛选。

例如,假设您正在构建一个套利(交易)应用程序。你有卖家提供的产品在一个价格和买家要求的产品在一个成本。你在产品键上做一个交叉连接(为了匹配潜在的买家和卖家) ,计算成本和价格之间的差额,然后对 Desc 进行排序。给你(中间人)最有利可图的交易执行。当然,几乎总是有其他的边界筛选条件。

这是一种使用到 创建交叉表报告的交叉连接的有趣方法。我在 Joe Celko 的聪明人 SQL中找到了它,并且使用了好几次。确实需要一些准备工作,但是花费的时间是值得的。

你可以使用 交叉连接:

  • 为测试目的产生数据
  • 结合所有特性-你需要所有可能的组合,例如血型(A,B,. .)和 Rh-/+ ,等等。 - 我不是这方面的专家;)
CREATE TABLE BL_GRP_01 (GR_1 text);
CREATE TABLE RH_VAL_01 (RH_VAL text);
INSERT INTO BL_GRP_01 VALUES ('A'), ('B'), ('AB'), ('O');
INSERT INTO RH_VAL_01 VALUES ('+'), ('-');


SELECT CONCAT(x.GR_1, y.RH_val)
FROM BL_GRP_01 x
CROSS JOIN RH_VAL_01 y
ORDER BY CONCAT(x.GR_1, y.RH_VAL);
  • create a join for 2 tables without a common id and then group it using max(),etc.. to find highest possible combination