AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 290833
Accepted
technazi
technazi
Asked: 2021-05-01 18:00:07 +0800 CST2021-05-01 18:00:07 +0800 CST 2021-05-01 18:00:07 +0800 CST

为什么 FROM 多个表默认为笛卡尔积?

  • 772

当我进行如下查询时,做笛卡尔积(交叉连接)背后的想法是什么 -

SELECT * FROM agents, orders

我认为它们会连接(如pandas)。添加表格而不是相乘感觉更自然。

只是好奇,并没有在互联网上找到默认笛卡尔积背后的理由。我假设FROM table1, table2根据 SQL 的语法对于交叉连接可能会更正确,但为什么呢?

sql-standard join
  • 4 4 个回答
  • 1188 Views

4 个回答

  • Voted
  1. Best Answer
    Bill Karwin
    2021-05-02T09:35:42+08:002021-05-02T09:35:42+08:00

    逗号样式连接 (SQL-89) 与使用JOIN关键字 (SQL-92) 的语法不是重点。您应该使用更现代的语法,但它没有解决如果您不指定条件,为什么默认会是笛卡尔积的问题。

    答案是它使关系代数起作用。

    笛卡尔积是两组元素的所有组合的集合。第一组的每个元素都与第二组的每个元素配对。

    关系是笛卡尔积的子集。这是一个笛卡尔积,加上一个测试任何给定元素对是否属于该关系的条件。

    但是默认条件是一个固定true值,所以每个配对都通过了测试。所以默认关系最终是笛卡尔积。

    我想另一种选择是将默认条件设为固定false值,因此默认关系将是空关系。

    这会使某些场景变得更容易,例如,如果您运行 aDELETE但不小心忘记了该WHERE子句,它将避免您删除整个表。

    WHERE但是随后我们会收到来自不同人的关于 Stack Overflow 的问题,他们问为什么默认连接是一个空集,因为当他们忘记查询子句SELECT并且他们的数据库似乎是空的时,这会让他们心跳加速。

    • 10
  2. J.D.
    2021-05-01T18:15:01+08:002021-05-01T18:15:01+08:00

    我不熟悉concatenate在Pandas中的工作方式,但我认为这CROSS JOIN是唯一有意义的子句,在这种情况下没有指定任何其他内容。

    您当然不能垂直连接(UNION在 SQL 中)表,因为它们的列可能不同(列数及其数据类型)以及如何水平连接它们,即在什么条件下可以将每个表中的行对齐到当没有指定任何内容时,将它们作为单行关联在一起?我认为在关系逻辑的上下文中最简单的答案是CROSS JOIN.

    此外,Pandas中的连接似乎意味着对与关系数据库不同类型的对象进行操作。虽然在技术上是的,但这些对象可以被视为一组值,但描述它们的标准和这些值所依据的约束与具有观察不同数据类型的列的关系记录表不同,并且可能受到数据库约束的约束, ETC。

    为了在 SQL 中实现与Pandas中单个连接操作类似的结果,您需要应用一系列操作,例如,可能包括、和。PIVOTUNIONCAST

    • 5
  3. user228900
    2021-05-01T20:47:14+08:002021-05-01T20:47:14+08:00

    Lennart的评论留下了答案:

    SQL 尝试实现在“大型共享数据库的数据关系模型” (pdf) 中定义的关系模型。

    我认为为什么选择符号“,”来表示其中一种操作和特别是笛卡尔积,我认为没有一个很好的答案。

    • 2
  4. Vérace
    2021-05-02T04:34:04+08:002021-05-02T04:34:04+08:00

    您不应该使用(,逗号)作为CROSS JOIN子句的代理来加入您的表。它提供了CROSS JOIN功能,但要付出代价——可读性、清晰性和明确性——后一个词意味着清晰和准确的质量(不确定它是否存在)!

    至于您关于“ why the comma”的问题(过去,但不再是 - 或者至少它已经失宠),请参阅下面的讨论!

    软件在维护模式下花费的时间比在开发中花费的时间更多,因此您的软件易于阅读和维护非常重要!

    ACROSS JOIN在逻辑上可以被认为是这样的(来自这里的漂亮图像):

    在此处输入图像描述

    另一种(同样有用的)看待这个的方法是(相同的链接):

    在此处输入图像描述

    因此,显然CROSS JOINs 具有有用的、日常的、实际的应用程序!

    考虑以下三个查询(请参阅此处的小提琴):

    SELECT * FROM meal, drink;
    

    结果(所有查询都相同):

    查询一:

    mname   dname
    Omlette Coffee
    Omlette Tea
    Omlette Orange Juice
    Fried Egg   Coffee
    Fried Egg   Tea
    Fried Egg   Orange Juice
    Sausage Coffee
    Sausage Tea
    Sausage Orange Juice
    9 rows
    

    因此,对于查看该查询的开发人员,他们可能会说:“有多少字段?”,“这些字段有什么作用?” 或“此查询的性能影响是什么?”。我们只是 0% 的方式变得明确!

    现在,这个:

    查询 2:

    SELECT *
    FROM meal
    CROSS JOIN drink;
    

    稍微清楚一点——至少我们可以从 10,000m 看到这是一个,因为CROSS JOIN这个术语是黑白的!所以,我们大约有 33% 的方式是明确的!

    最后,考虑这个(最好的):

    查询 3:

    SELECT m.mname, d.dname 
    FROM meal m
    CROSS JOIN drink d;
    

    所以,现在,我们尽可能明确。有一个替代方案,那就是(稍微降低清晰度 - 但比逗号更清晰!):

    最后,

    查询 4(也运行...):

    SELECT m.mname, d.dname 
    FROM meal m
    JOIN drink d ON TRUE;  -- or 1 = 1;
    

    我会敦促你看看这篇优秀的文章(显式编码纪律- BIG ONE是第 3 名):

      1. 为什么显式很重要
      1. 显式命名
      1. 避免使用显式代码的技巧
      1. 结论(以下引用):

    作者将其总结为:

    显式编码规则倾向于在代码中清晰明确地表达意图。

    它建议为变量、函数、类和其他结构编写有意义的名称。它建议避免棘手的解决方案,以利于阅读和明确的意图。

    为什么是逗号?

    至于逗号——它只是一种语法、符号——可能,如果现在正在设计 SQL ,它不会是作为表方式的第一选择(或任何选择)CROSS JOIN。术语CONCAT JOIN(à la Python 语法......)可能是一个潜在的候选者(对于从头设计) - 但现在我们(SQL 开发人员/DBA)已经习惯了,这听起来很奇怪CROSS JOIN。

    此外,查询中各个字段的分隔符是逗号:

    SELECT t1.f1, t2.f2
    FROM t1
    JOIN t1
      ON t1.k = t2.fk
    

    因此,它可能(在我之前......)将它用作表格分隔符也是合乎逻辑的。

    最重要的是表达的清晰,不要忘记 SQL比 Python 早很多(约 20 年),而且许多语言都有过去的遗留物,最好将其删除 - 但只要考虑中断从Python 2 到 Python 3 - 已经(并且继续)造成了重大困难(作为记录,我钦佩 Guido van Rossum 做出改变的勇气 - 代码损坏......)。

    SQL 的问题在于它是由委员会设计的,至少从我的经验来看,“ courage”不是我会与委员会联系起来的特征!:-) 逗号已经失宠,许多严肃的从业者不鼓励它,但它并没有(不幸地)随着 更清晰的ANSIJOIN的到来而被淘汰。

    ps 欢迎来到论坛!

    • 2

相关问题

  • SQL 返回另一个表中选项的答案数为 0

  • 我可以自动执行 MySQL 查询中的“on”语句吗?

  • 顶级数据库供应商的 SQL (DML-) 方言之间有何不同?

  • INNER JOIN 和 OUTER JOIN 有什么区别?

  • JOIN 语句的输出是什么样的?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve