Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.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或MySQL中是否不使用JOIN关键字?_Sql_Mysql_Join - Fatal编程技术网

不使用';在SQL或MySQL中是否不使用JOIN关键字?

不使用';在SQL或MySQL中是否不使用JOIN关键字?,sql,mysql,join,Sql,Mysql,Join,当我开始编写数据库查询时,我还不知道JOIN关键字,自然地,我只是扩展了我已经知道的内容,并编写了如下查询: SELECT a.someRow, b.someRow FROM tableA AS a, tableB AS b WHERE a.ID=b.ID AND b.ID= $someVar 现在我知道这与内部连接相同,我在代码中找到所有这些查询,并问自己是否应该重写它们。他们身上有什么难闻的东西吗?还是他们很好 编辑: 我的答案摘要:此查询没有问题,但使用关键字很可能会使代码更可读/

当我开始编写数据库查询时,我还不知道JOIN关键字,自然地,我只是扩展了我已经知道的内容,并编写了如下查询:

SELECT a.someRow, b.someRow 
FROM tableA AS a, tableB AS b 
WHERE a.ID=b.ID AND b.ID= $someVar
现在我知道这与内部连接相同,我在代码中找到所有这些查询,并问自己是否应该重写它们。他们身上有什么难闻的东西吗?还是他们很好


编辑:

我的答案摘要:此查询没有问题,但使用关键字很可能会使代码更可读/更易于维护

我的结论:我不会改变我以前的疑问,但我会纠正我的写作风格,并在将来使用关键词


谢谢你的回答

示例中的语法没有问题。“内部连接”语法通常被称为“ANSI”语法,它是在示例中所示的样式之后出现的。它的存在是为了阐明连接的类型/方向/组成部分,但在功能上通常与您所拥有的不同

对“ANSI”联接的支持是基于数据库平台的,但现在它或多或少是通用的

作为旁注,“ANSI”语法的一个补充是“完全外部连接”或“完全连接”


希望这有帮助。

我避免隐式连接;当查询非常大时,它们会使代码难以破译


通过显式连接和良好的格式,代码更易于阅读和理解,无需注释。

它更多地是一种语法选择。我更喜欢将连接条件与连接分组,因此我使用内部连接语法

SELECT a.someRow, b.someRow
FROM tableA AS a
INNER JOIN tableB AS b
  ON a.ID = b.ID
WHERE b.ID = ?

(?作为占位符)

更详细的
内部联接、左外部联接、右外部联接、完全外部联接
来自ANSI SQL/92联接语法。对我来说,这种冗长的内容让开发人员/DBA更清楚地了解连接的意图。

在SQL Server中,总是有查询计划要检查,可以按如下方式进行文本输出:

SET SHOWPLAN_ALL ON
GO

DECLARE @TABLE_A TABLE
(
    ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Data VARCHAR(10) NOT NULL
)
INSERT INTO @TABLE_A
SELECT 'ABC' UNION 
SELECT 'DEF' UNION
SELECT 'GHI' UNION
SELECT 'JKL' 

DECLARE @TABLE_B TABLE
(
    ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Data VARCHAR(10) NOT NULL
)
INSERT INTO @TABLE_B
SELECT 'ABC' UNION 
SELECT 'DEF' UNION
SELECT 'GHI' UNION
SELECT 'JKL' 

SELECT A.Data, B.Data
FROM
    @TABLE_A AS A, @TABLE_B AS B
WHERE
    A.ID = B.ID

SELECT A.Data, B.Data
FROM
    @TABLE_A AS A
    INNER JOIN @TABLE_B AS B ON A.ID = B.ID
现在,我将省略table变量creates的计划,但两个查询的计划是相同的:

 SELECT A.Data, B.Data  FROM   @TABLE_A AS A, @TABLE_B AS B  WHERE   A.ID = B.ID
  |--Nested Loops(Inner Join, OUTER REFERENCES:([A].[ID]))
       |--Clustered Index Scan(OBJECT:(@TABLE_A AS [A]))
       |--Clustered Index Seek(OBJECT:(@TABLE_B AS [B]), SEEK:([B].[ID]=@TABLE_A.[ID] as [A].[ID]) ORDERED FORWARD)
 SELECT A.Data, B.Data  FROM   @TABLE_A AS A   INNER JOIN @TABLE_B AS B ON A.ID = B.ID
  |--Nested Loops(Inner Join, OUTER REFERENCES:([A].[ID]))
       |--Clustered Index Scan(OBJECT:(@TABLE_A AS [A]))
       |--Clustered Index Seek(OBJECT:(@TABLE_B AS [B]), SEEK:([B].[ID]=@TABLE_A.[ID] as [A].[ID]) ORDERED FORWARD)

因此,简短的回答-无需重写,除非每次维护它们时都花很长时间试图读取它们?

这还取决于您是以这种方式进行内部联接还是以外部联接。例如,WHERE子句(=*和*=)中用于外部联接的MS SQL Server语法可能会产生与外部联接语法不同的结果,SQL Server 2005中不再支持()这种语法。

在某些常见情况下,仅使用
其中的
过滤联接可能效率极低。例如:

SELECT * FROM people p, companies c 
    WHERE p.companyID = c.id AND p.firstName = 'Daniel'
大多数数据库都会按字面意思执行此查询,首先对
人员
公司
表进行排序,然后根据具有匹配的
公司id
id
字段的表进行筛选。虽然完全不受约束的乘积不存在于任何地方,但它只存在于内存中,并且只存在一瞬间,它的计算确实需要一些时间

更好的方法是在相关的地方使用
JOIN
s对约束进行分组。这不仅主观上更容易阅读,而且效率更高。因此:

SELECT * FROM people p JOIN companies c ON p.companyID = c.id
    WHERE p.firstName = 'Daniel'
它稍微长一点,但数据库能够查看
ON
子句,并使用它直接计算完全约束的
连接,而不是从所有内容开始,然后限制。计算速度更快(特别是对于大型数据集和/或许多表联接),并且需要更少的内存

我更改我看到的每个使用“逗号
JOIN
”语法的查询。在我看来,它存在的唯一目的就是简洁。考虑到性能影响,我认为这不是一个令人信服的理由。

一般来说:

使用JOIN关键字链接(即“JOIN”)主键和外键


使用WHERE子句将结果集限制为您感兴趣的记录

可能出现的一个问题是,在同一个查询中尝试混合使用旧的“逗号样式”联接与SQL-92联接,例如,如果需要一个内部联接和另一个外部联接

SELECT *
FROM table1 AS a, table2 AS b
 LEFT OUTER JOIN table3 AS c ON a.column1 = c.column1
WHERE a.column2 = b.column2;
问题在于,最新的SQL标准规定连接在逗号连接之前进行计算。因此ON子句中对“a”的引用给出了一个错误,因为在对ON子句求值时还没有定义相关名称。这是一个非常令人困惑的错误

解决方案是不要混合使用这两种连接样式。您可以在旧代码中继续使用逗号样式,但如果编写新查询,请将所有连接转换为SQL-92样式

SELECT *
FROM table1 AS a
 INNER JOIN table2 AS b ON a.column2 = b.column2
 LEFT OUTER JOIN table3 AS c ON a.column1 = c.column1;

旧连接语法中要考虑的另一件事是,由于没有ON子句,所以很容易意外地得到一个CARTEXIN连接。如果Distinct关键字在查询中,并且它使用旧式联接,请将其转换为ANSI标准联接,然后查看是否仍然需要Distinct关键字。如果以这种方式修复意外的笛卡尔联接,则可以通过重写来指定联接和联接字段,从而极大地提高性能。

能否提供在旧联接语法上执行笛卡尔乘积的数据库系统的示例?旧语法非常常见,我想大多数DBMS优化器都知道不要这样做。StackOverflow中肯定需要[引证需求],请您的DBMS向您解释这两种说法。一个好的系统将使用旧的SQL和SQL1992连接语法执行等效的操作。不是这样。许多关系数据库(DB2、Oracle、Sybase)早于SQL-92连接语法。在此之前,所有连接谓词都在WHERE子句中。缺少连接谓词是导致笛卡尔乘积的原因。大多数数据库选择高效的访问路径,并且只有当路径具有最低的计算成本(或者如果它是唯一的访问路径)时才选择“笛卡尔乘积”