ChatGPT解决这个技术问题 Extra ChatGPT

交叉连接的用途是什么?

交叉连接对两组元组执行笛卡尔积。

SELECT *
FROM Table1
CROSS JOIN Table2

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

很遗憾这个问题已经结束了。我认为它可以被标记为 Community Wiki,但说它没有建设性是不公平的。
我同意。这回答了我的确切问题。
有时,新开发人员难以理解他们正在使用的软件的某些功能的含义。像这样的问题对新开发人员特别有帮助,主要是因为接下来的讨论阐明了初级开发人员从未考虑过的许多可能性。问题的格式充其量是基本的,但意图似乎是诚实的,因为它问“为什么会存在?”我同意 Wayne Koorts 的观点,很遗憾 casperOne 选择关闭它并称其“没有建设性”。 “没有建设性”的部分特别让我恼火。

D
Dave DuPlantis

如果您有一个想要完全填充的“网格”,例如特定服装的尺寸和颜色信息:

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 将及时通知您遗漏。通常他或她不会高兴。


...在这种情况下,您的 DBA 将及时通知您遗漏。通常他或她不会高兴。 ……哈哈,太真实了!
@Dave:第二个例子不会只是小时 CROSS JOIN 分钟吗?
@Rakesh,很好,我在想一些我正在输入的东西。固定的。
我可以想象,如果给您两组 id(可能是 csv 格式),则交叉连接非常实用,一组包含员工 ID,另一组包含任务 ID。这个想法是你有一个 EmployeeTask 的 M2M 表。您可以使用交叉连接将每个给定任务分配给每个给定员工,前提是您将 csv 转换为表变量(或其他东西)。
O
Ovidiu Pacurar

生成测试数据。


我从没想过我会看到一个 4 字的“答案”得到 9 个赞。
好吧,现在您有一个更好的选择: generatedata.com
R
Randy

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

我想你可能想要的一个人为的例子是,如果你有一张员工表和一张需要做的工作表,并且想要查看一名员工对一项工作的所有可能分配。


K
Kevin Dostalek

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

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


啊!这个解释对我来说最有意义。在这种情况下,INNER JOIN 没有意义,因为产品 ID 和卖家之间没有关系,因为多个卖家可以销售相同的产品。
J
James Curran

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

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

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

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

这就解释了为什么一个唯一意义在于它只有一行的表的名称意味着“两个”。


J
Joel Coehoorn

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


J
Jeff Jones

这是对 create a crosstab report 使用交叉联接的一种有趣方式。我在 Joe Celko's SQL For Smarties 中找到了它,并且已经使用了好几次。它确实需要一些设置,但值得投入时间。


t
thoroughly

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


C
Community

您可以使用它 CROSS JOIN 来:

为测试目的生成数据

结合所有属性-您需要所有可能的组合,例如血型(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);

为没有共同 id 的 2 个表创建连接,然后使用 max() 等对其进行分组。以找到可能的最高组合