Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL内部联接语法_Sql_Syntax_Inner Join_Cross Join - Fatal编程技术网

SQL内部联接语法

SQL内部联接语法,sql,syntax,inner-join,cross-join,Sql,Syntax,Inner Join,Cross Join,下面的两位SQL得到相同的结果 SELECT c.name, o.product FROM customer c, order o WHERE c.id = o.cust_id AND o.value = 150 SELECT c.name, o.product FROM customer c INNER JOIN order o on c.id = o.cust_id WHERE o.value = 150 我见过这两种风格在不同的公司被作为标准。据我所见,第二

下面的两位SQL得到相同的结果

SELECT c.name, o.product  
FROM customer c, order o  
WHERE c.id = o.cust_id  
AND o.value = 150  

SELECT c.name, o.product  
FROM customer c  
INNER JOIN order o on c.id = o.cust_id  
WHERE o.value = 150
我见过这两种风格在不同的公司被作为标准。据我所见,第二个是大多数人在网上推荐的。除了风格之外,还有什么真正的原因吗?使用内部联接有时会有更好的性能吗

我注意到安格尔和Oracle开发人员倾向于使用第一种风格,而Microsoft SQL Server用户倾向于使用第二种风格,但这可能只是巧合

谢谢你的见解,我想知道这一点已经有一段时间了


编辑:由于使用了不正确的术语,我将标题从“SQL内部联接与笛卡尔积”更改为“SQL内部联接与笛卡尔积”。感谢到目前为止的所有回复。

两个查询都在执行内部联接,只是语法不同。

实际上,这些示例是等效的,两者都不是笛卡尔积。当您在不指定联接条件的情况下联接两个表时,将返回笛卡尔积,例如

select *
from t1,t2

关于这一点,我们进行了很好的讨论。

为了回答您的部分问题,我认为早期的bug在加入。。。Oracle中的ON语法不鼓励Oracle用户使用该语法。我认为现在没有什么特别的问题


它们是等价的,应该解析为相同的内部表示形式以进行优化

Oracle支持加入的时间较晚。。。关于(ANSI)语法(直到Oracle 9),这就是Oracle开发人员经常不使用它的原因

就我个人而言,当逻辑上很清楚一个表驱动查询,而其他表是查找表时,我更喜欢使用ANSI语法。当表“相等”时,我倾向于使用笛卡尔语法


性能应该不会有任何不同。

两个查询都是内部连接,并且是等效的。第一种是较旧的操作方法,而连接语法的使用只是在引入SQL-92标准后才变得普遍(我相信这是在较旧的定义中,只是在此之前没有得到特别广泛的使用)

强烈推荐使用连接语法,因为它将连接逻辑与WHERE子句中的过滤逻辑分离。虽然连接语法实际上是内部连接的语法糖,但它的优势在于外部连接,在这种情况下,旧的*语法可能会产生无法明确描述连接的情况,并且解释依赖于实现。[LEFT | RIGHT]JOIN语法避免了这些缺陷,因此为了保持一致性,最好在所有情况下都使用JOIN子句

请注意,这两个示例都不是笛卡尔积。你也可以用这两种方法

SELECT c.name, o.product  
FROM customer c, order o  
WHERE o.value = 150  


加入。。。在…上语法是ANSI和ISO SQL规范的最新补充。加入。。。在…上语法通常是首选的,因为它1)将连接条件移出WHERE子句,使WHERE子句仅用于过滤;2)如果您正在创建一个可怕的笛卡尔积,则它会更明显,因为每个连接必须至少伴随一个ON子句。如果WHERE子句中的所有连接条件都是AND,那么当缺少一个或多个连接条件时,情况就不那么明显了。

TL;博士 内部联接语句可以重写为交叉联接,其中WHERE子句与内部联接查询的ON子句中使用的条件相同

表关系 考虑到我们有以下
post
post\u comment
表格:

post
具有以下记录:

| id | title     |
|----|-----------|
| 1  | Java      |
| 2  | Hibernate |
| 3  | JPA       |
post_comment
有以下三行:

| id | review    | post_id |
|----|-----------|---------|
| 1  | Good      | 1       |
| 2  | Excellent | 1       |
| 3  | Awesome   | 2       |
SQL内部联接 SQL JOIN子句允许您关联属于不同表的行。例如,a将创建一个笛卡尔积,其中包含两个连接表之间所有可能的行组合

虽然交叉联接在某些情况下很有用,但大多数情况下,您希望根据特定条件联接表。这就是内部连接发挥作用的地方

SQL内部联接允许我们根据通过on子句指定的条件过滤联接两个表的笛卡尔积

SQL内部联接-在“始终为真”条件下 如果提供“始终为真”条件,内部联接将不会过滤联接的记录,结果集将包含两个联接表的笛卡尔积

例如,如果执行以下SQL内部联接查询:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
我们将获得
post
post\u comment
记录的所有组合:

| p.id    | pc.id      |
|---------|------------|
| 1       | 1          |
| 1       | 2          |
| 1       | 3          |
| 2       | 1          |
| 2       | 2          |
| 2       | 3          |
| 3       | 1          |
| 3       | 2          |
| 3       | 3          |
因此,如果ON子句条件为“always true”,则内部连接仅等效于交叉连接查询:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
SQL内部联接-在“始终为false”条件下 另一方面,如果On子句条件为“always false”,则所有连接的记录都将被过滤掉,结果集将为空

因此,如果我们执行以下SQL内部联接查询:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
我们不会得到任何结果:

| p.id    | pc.id      |
|---------|------------|
这是因为上面的查询相当于以下交叉连接查询:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
使用外键列和主键列的SQL内部JOIN-ON子句 最常见的ON子句条件是将子表中的外键列与父表中的主键列相匹配的条件,如以下查询所示:

SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p
INNER JOIN post_comment pc ON pc.post_id = p.id
ORDER BY p.id, pc.id
执行上述SQL内部联接查询时,我们得到以下结果集:

| p.id    | pc.post_id | pc.id      | p.title    | pc.review |
|---------|------------|------------|------------|-----------|
| 1       | 1          | 1          | Java       | Good      |
| 1       | 1          | 2          | Java       | Excellent |
| 2       | 2          | 3          | Hibernate  | Awesome   |
因此,查询结果集中只包括与ON子句条件匹配的记录。在我们的例子中,结果集包含所有
post
以及它们的
post\u注释
记录。没有关联的
post\u注释的
post
行被排除在外,因为它们不能满足ON子句条件

同样,上述SQL内部联接查询相当于以下交叉联接查询:

SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 1
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 1
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
INNER JOIN post_comment pc ON 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.id AS "pc.id"
FROM post p
CROSS JOIN post_comment
WHERE 1 = 0
ORDER BY p.id, pc.id
SELECT
   p.id AS "p.id",
   pc.post_id AS "pc.post_id",
   pc.id AS "pc.id",
   p.title AS "p.title",
   pc.review  AS "pc.review"
FROM post p, post_comment pc
WHERE pc.post_id = p.id
未删除的行是满足WHERE子句的行,只有这些记录才会包含在结果集中。这就是问题所在