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

SELECT *
FROM Table1
CROSS JOIN Table2

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

有帮助吗?

解决方案

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

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

其他提示

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

我想你可能想要的一个人为设想的例子是,如果你有一张员工表和一份需要做的工作表,并希望看到一个员工的所有可能的工作分配给一个工作。

生成测试数据。

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

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

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

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

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

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

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

采用数字表格,数字0-9有10行。您可以在该表上使用交叉连接几次,以获得具有所需行数的结果,并且结果编号相应。这有很多用途。例如,您可以将它与datadd()函数结合使用,以获取给定年份中每天的集合。

这是一种使用交叉联接的有趣方式创建交叉表报告。我在 Joe Celko的SQL For Smarties 中找到了它,并且多次使用它。它确实需要一些设置,但值得投入时间。

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

你可以用它 交叉连接 到:- 生成用于测试目的的数据 - 结合所有属性 - 您需要所有可能的组合,例如血型(A,B,..)与Rh-/+等...--根据您的目的调整它;) - 我不是这方面的专家;)

CREATE TABLE "HR"."BL_GRP_01" 
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);

CREATE TABLE "HR"."BL_GRP_02" 
("GR_1" VARCHAR2(5 BYTE));

REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);

CREATE TABLE "HR"."RH_VAL_01" 
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);

select distinct  a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;
  • 为没有公共 id 的 2 个表创建联接,然后使用 max() 等对其进行分组。找到最高可能的组合
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top