交叉连接有什么用途?
交叉连接对两个集合的元组执行笛卡尔积。
SELECT *
FROM Table1
CROSS JOIN Table2
哪些情况下这样的 SQL 操作特别有用?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
交叉连接对两个集合的元组执行笛卡尔积。
SELECT *
FROM Table1
CROSS JOIN Table2
哪些情况下这样的 SQL 操作特别有用?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(9)
如果您有一个想要完全填充的“网格”,例如特定服装的尺寸和颜色信息:
也许您想要一个包含一天中每一分钟的行的表格,并且您想用它来验证每分钟都会执行一个过程,因此您可能会交叉三个表:
或者您有一组标准报告规范,希望应用于一年中的每个月:
将这些规范维护为视图的问题是,在大多数情况下,您不想要完整的产品,特别是在衣服方面。 您可以向查询添加
MINUS
逻辑来删除您不包含的某些组合,但您可能会发现以其他方式填充表而不使用笛卡尔积会更容易。此外,您最终可能会在行数可能比您想象的多的表上尝试交叉联接,或者您的
WHERE
子句可能部分或完全丢失。 在这种情况下,您的 DBA 将立即通知您该遗漏。 通常他或她不会高兴。If you have a "grid" that you want to populate completely, like size and color information for a particular article of clothing:
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:
Or you have a set of standard report specs that you want to apply to every month in the year:
The problem with maintaining these as views is that in most cases, you don't want a complete product, particularly with respect to clothes. You can add
MINUS
logic to the query to remove certain combinations that you don't carry, but you might find it easier to populate a table some other way and not use a Cartesian product.Also, you might end up trying the cross join on tables that have perhaps a few more rows than you thought, or perhaps your
WHERE
clause was partially or completely missing. In that case, your DBA will notify you promptly of the omission. Usually he or she will not be happy.生成用于测试的数据。
Generate data for testing.
对于大多数数据库查询,您通常不需要完整的笛卡尔积。 关系数据库的全部功能在于,您可以应用您可能感兴趣的任何限制,以避免从数据库中提取不必要的行。
我想一个您可能想要的人为示例是,如果您有一张员工表和一张需要执行的工作表,并且希望查看一名员工对一项工作的所有可能分配。
You're typically not going to want a full Cartesian product for most database queries. The whole power of relational databases is that you can apply whatever restrictions you might be interested in to allow you to avoid pulling unnecessary rows from the db.
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.
好吧,这可能无法回答这个问题,但是,如果这是真的(我什至不确定),这就是一段有趣的历史。
在 Oracle 的早期,一位开发人员意识到他需要复制表中的每一行(例如,它可能是一个事件表,他需要将其更改为单独的“开始事件”和“结束事件”)条目)。 他意识到,如果他的表只有两行,他可以进行交叉连接,仅选择第一个表中的列,并准确获得他需要的内容。 因此,他创建了一个简单的表,他自然地将其称为“DUAL”。
后来,他需要做一些只能通过从表中选择来完成的事情,即使该操作本身与表无关(也许他忘记了手表并想通过 SELECT SYSDATE FROM.. 读取时间) .)他意识到他的 DUAL 桌子仍然放在周围,并使用了它。 过了一会儿,他厌倦了看到时间打印两次,所以他最终删除了其中一行。
Oracle 的其他人开始使用他的表,最终决定将其包含在标准 Oracle 安装中。
这解释了为什么一个唯一意义在于只有一行的表有一个意思是“二”的名称。
Ok, this probably won't answer the question, but, if it's true (and I'm not even sure of that) it's a fun bit of history.
In the early days of Oracle, one of the developers realized that he needed to duplicate every row in a table (for example, it's possible it was a table of events and he needed to change it separate "start event" and "end event" entries). He realized that if he had a table with just two rows, he could do a cross join, selecting just the columns in the first table, and get exactly had he needed. So he created a simple table, which he naturally enough called "DUAL".
Later, he need to do something which could only be done via a select from a table, even though the action itself had nothing to do with the table, (perhaps he forgot his watch and wanted to read the time via SELECT SYSDATE FROM...) He realized that he still had his DUAL table lying around, and used that. After a while, he tired of seeing the time printed twice, so he eventual deleted one of the rows.
Others at Oracle started using his table, and eventually, it was decided to include it in the standard Oracle installation.
Which explains why a table whose only significance is that it has one row has a name which means "two".
关键是“显示所有可能的组合”。 我将它们与其他计算字段结合使用,然后对它们进行排序/过滤。
例如,假设您正在构建一个套利(交易)应用程序。 卖家以一定的价格提供产品,而买家则以一定的成本索取产品。 您对产品密钥进行交叉连接(以匹配潜在的买家和卖家),计算成本和价格之间的价差,然后对 desc 进行排序。 以此为您(中间人)提供最有利可图的交易执行。 当然,几乎总是您会有其他边界过滤条件。
The key is "show me all possible combinations". I've used these in conjunction with other calculated fields an then sorted/filtered those.
For example, say you are building an arbitrage (trading) application. You have sellers offering products at a price and buyers asking for products at a cost. You do a cross join on the product key (to match up the potential buyers and sellers), calculate the spread between cost and price, then sort desc. on this to give you (the middleman) the most profitable trades to execute. Almost always you'll have other bounding filter criteria of course.
类似于数字表,其中有 10 行代表数字 0-9。 您可以在该表上使用几次交叉联接来获得包含所需行数的结果,并且每行都会进行适当的编号。 这有很多用途。 例如,您可以将其与 dateadd() 函数结合起来,以获得给定年份中每一天的集合。
注意:这篇文章现在已经很旧了。 今天我会使用
generate_series()
或递归 CTE 来完成这项工作。Takes something like a digits table, which has ten rows for the digits 0-9. You can use cross join on that table a few times to a get a result with however many rows you need, and each row will be numbered appropriately. This has a number of uses. For example, you can combine it with a dateadd() function to get a set for every day in a given year.
Note: this post is old now. Today I'd use
generate_series()
or a recursive CTE to do this job instead.这是使用交叉联接创建交叉表报告。 我在 Joe Celko 的 SQL For Smarties 中找到了它,并使用了多次。 它确实需要一些设置,但值得投入时间。
This is an interesting way to use a cross join to create a crosstab report. I found it in Joe Celko's SQL For Smarties, and have used it several times. It does take a little setup, but has been worth the time invested.
您可以使用它CROSS JOIN来:
--根据您的目的进行调整;) - 我不是这方面的专家;)
you can use it CROSS JOIN to:
--tune it for your purposes;) - I'm not expert in this area;)
想象一下,您想要针对特定的商品和日期组合(价格、可用性等)发出一系列查询。 您可以将项目和日期加载到单独的临时表中,并使查询交叉连接表。 这可能比枚举 IN 子句中的项目和日期更方便,特别是因为某些数据库限制 IN 子句中的元素数量。
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.