代码之家  ›  专栏  ›  技术社区  ›  Llyle

交叉连接的用途是什么?

  •  118
  • Llyle  · 技术社区  · 17 年前

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

    SELECT *
    FROM Table1
    CROSS JOIN Table2
    

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

    9 回复  |  直到 16 年前
        1
  •  101
  •   Dave DuPlantis    12 年前

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

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

        2
  •  25
  •   Ovidiu Pacurar    17 年前

    生成测试数据。

        3
  •  14
  •   Randy    17 年前

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

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

        4
  •  12
  •   James Curran    8 年前

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

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

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

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

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

        5
  •  10
  •   Kevin Dostalek    17 年前

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

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

        6
  •  3
  •   Joel Coehoorn    17 年前

    采用类似于数字表的方式,该表有十行数字0-9。您可以在该表上使用交叉连接几次,以获得所需行数的结果,并且每一行都会被适当地编号。这有很多用途。例如,您可以将其与dateadd()函数结合使用,以获取给定年份中每天的集合。


    注意:这篇文章已经过时了。今天我会用 generate_series() 或者使用递归CTE来完成这项工作。

        7
  •  2
  •   Jeff Jones    17 年前

    这是一种使用交叉连接的有趣方法 create a crosstab report 我在里面找到的 Joe Celko's SQL For Smarties ,并已多次使用。它确实需要一点设置,但值得投入时间。

        8
  •  1
  •   thoroughly    17 年前

    你可以用它 交叉连接 致:

    • 生成用于测试目的的数据
    • 结合所有属性-您需要所有可能的组合,例如血型(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);
    
    • 为2个没有公共id的表创建一个联接,然后使用max()等对其进行分组。以找到尽可能高的组合
        9
  •  1
  •   Community Mohan Dere    5 年前

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

    推荐文章