只是对 SQL 加入感到好奇
Just curious about SQL Joins
我只是好奇。如果我有两个 table,比如说客户和订单。
客户端有一个唯一的主键 ID_Client。订单也有一个 ID_Client 字段和一个关系,以通过 ID_Client 字段保持与客户的 table 的完整性。
所以当我想加入两个 table 时,我会这样做:
SELECT
Orders.*, Clients.Name
FROM
Orders
INNER JOIN
Clients ON Clients.ID_Client = Orders.ID_Client
因此,如果我负责创建主键以及 table 之间的关系,
为什么我需要在 on 子句中显式包含连接的列?
为什么我不能做类似的事情:
SELECT
Orders.*, Clients.Name
FROM
Orders
INNER JOIN
Clients
所以 SQL 应该知道哪些列与 table 相关...
是这样的。 :)
sql 标准规定您必须说明要加入哪些列。这些约束只是为了参照完整性。使用 mysql 连接支持 "join table using (column1, column2)" 但是这些列必须出现在两个表中
如果您不在查询中明确给出字段名称,SQL 不知道要使用哪些字段。您不会总是拥有名称相同的字段,也不会总是加入主键。例如,关系可以存在于名为 "Client_Address" 和 "Delivery_Address" 的两个外键字段之间。在这种情况下,您可以很容易地看到您需要如何提供字段名称。
举个例子:
SELECT o.*, c.Name
FROM Clients c
INNER JOIN Orders o
ON o.Delivery_Address = c.Client_Address
Is there a reason why do i need to explicit include then joinned fields in on clause?
是的,因为您仍然需要告诉数据库服务器您想要什么。 "Do what I mean" 到目前为止,不在任何软件系统的能力范围内。
外键是确保数据完整性的工具。它们不规定您如何连接表。您可以在可通过 SQL 表达式.
表达的任何条件下加入
换句话说,连接子句通过一个可自由定义的条件将两个表相互关联,该条件需要在给定连接左侧和右侧的两行的情况下评估为真。不一定是外键,可以是任何条件。
想找到姓氏与您销售的产品相同的人吗?
SELECT
Products.Name,
Clients.LastName
FROM
Products
INNER JOIN Clients ON Products.Name = Clients.LastName
Products 和 Clients 之间甚至没有外键,整个事情仍然有效。
此行为不是默认行为的原因
因为一个 Table 可以有多个列引用回另一个 table 中的一个列。
在许多遗留数据库中,没有外键约束,但列“应该是”引用其他 table 中的某些列。
连接条件并不总是像 A.Column = B.Column 那样简单。清单还在继续……
Microsoft 开发人员足够聪明,让我们做出这个决定,而不是他们猜测它永远是 A.Column = B.Column
我曾经遇到过同样的问题,我在 Database Administrator Stack Exchange 上找到了很好的解释,下面的答案是我认为最好的,但你可以参考 link 也可以得到额外的解释。
A foreign key is meant to constrain the data. ie enforce
referential integrity. That's it. Nothing else.
You can have multiple foreign keys to the same table. Consider the following where a shipment has a starting point, and an ending point.
table: USA_States
StateID
StateName
table: Shipment
ShipmentID
PickupStateID Foreign key
DeliveryStateID Foreign key
You may want to join based on the pickup state. Maybe you want to join on the delivery state. Maybe you want to perform 2 joins for
both! The sql engine has no way of knowing what you want.
You'll often cross join scalar values. Although scalars are usually the result of intermediate calculations, sometimes you'll have a
special purpose table with exactly 1 record. If the engine tried to
detect a foriegn key for the join.... it wouldn't make sense because
cross joins never match up a column.
In some special cases you'll join on columns where neither is unique. Therefore the presence of a PK/FK on those columns is
impossible.
You may think points 2 and 3 above are not relevant since your questions is about when there IS a single PK/FK relationship
between tables. However the presence of single PK/FK between the
tables does not mean you can't have other fields to join on in
addition to the PK/FK. The sql engine would not know which fields you
want to join on.
Lets say you have a table "USA_States", and 5 other tables with a FK to the states. The "five" tables also have a few foreign keys to
each other. Should the sql engine automatically join the "five" tables
with "USA_States"? Or should it join the "five" to each other? Both?
You could set up the relationships so that the sql engine enters an
infinite loop trying to join stuff together. In this situation it's
impossible fore the sql engine to guess what you want.
In summary: PK/FK has nothing to do with table joins. They are separate unrelated things. It's just an accident of nature that you
often join on the PK/FK columns.
Would you want the sql engine to guess if it's a full, left, right, or
inner join? I don't think so. Although that would arguably be a lesser
sin than guessing the columns to join on.
我只是好奇。如果我有两个 table,比如说客户和订单。 客户端有一个唯一的主键 ID_Client。订单也有一个 ID_Client 字段和一个关系,以通过 ID_Client 字段保持与客户的 table 的完整性。
所以当我想加入两个 table 时,我会这样做:
SELECT
Orders.*, Clients.Name
FROM
Orders
INNER JOIN
Clients ON Clients.ID_Client = Orders.ID_Client
因此,如果我负责创建主键以及 table 之间的关系,
为什么我需要在 on 子句中显式包含连接的列?
为什么我不能做类似的事情:
SELECT
Orders.*, Clients.Name
FROM
Orders
INNER JOIN
Clients
所以 SQL 应该知道哪些列与 table 相关...
是这样的。 :)
sql 标准规定您必须说明要加入哪些列。这些约束只是为了参照完整性。使用 mysql 连接支持 "join table using (column1, column2)" 但是这些列必须出现在两个表中
如果您不在查询中明确给出字段名称,SQL 不知道要使用哪些字段。您不会总是拥有名称相同的字段,也不会总是加入主键。例如,关系可以存在于名为 "Client_Address" 和 "Delivery_Address" 的两个外键字段之间。在这种情况下,您可以很容易地看到您需要如何提供字段名称。
举个例子:
SELECT o.*, c.Name
FROM Clients c
INNER JOIN Orders o
ON o.Delivery_Address = c.Client_Address
Is there a reason why do i need to explicit include then joinned fields in on clause?
是的,因为您仍然需要告诉数据库服务器您想要什么。 "Do what I mean" 到目前为止,不在任何软件系统的能力范围内。
外键是确保数据完整性的工具。它们不规定您如何连接表。您可以在可通过 SQL 表达式.
表达的任何条件下加入换句话说,连接子句通过一个可自由定义的条件将两个表相互关联,该条件需要在给定连接左侧和右侧的两行的情况下评估为真。不一定是外键,可以是任何条件。
想找到姓氏与您销售的产品相同的人吗?
SELECT
Products.Name,
Clients.LastName
FROM
Products
INNER JOIN Clients ON Products.Name = Clients.LastName
Products 和 Clients 之间甚至没有外键,整个事情仍然有效。
此行为不是默认行为的原因
因为一个 Table 可以有多个列引用回另一个 table 中的一个列。
在许多遗留数据库中,没有外键约束,但列“应该是”引用其他 table 中的某些列。
连接条件并不总是像 A.Column = B.Column 那样简单。清单还在继续……
Microsoft 开发人员足够聪明,让我们做出这个决定,而不是他们猜测它永远是 A.Column = B.Column
我曾经遇到过同样的问题,我在 Database Administrator Stack Exchange 上找到了很好的解释,下面的答案是我认为最好的,但你可以参考 link 也可以得到额外的解释。
A foreign key is meant to constrain the data. ie enforce referential integrity. That's it. Nothing else.
You can have multiple foreign keys to the same table. Consider the following where a shipment has a starting point, and an ending point.
table: USA_States StateID StateName table: Shipment ShipmentID PickupStateID Foreign key DeliveryStateID Foreign key
You may want to join based on the pickup state. Maybe you want to join on the delivery state. Maybe you want to perform 2 joins for both! The sql engine has no way of knowing what you want.
You'll often cross join scalar values. Although scalars are usually the result of intermediate calculations, sometimes you'll have a special purpose table with exactly 1 record. If the engine tried to detect a foriegn key for the join.... it wouldn't make sense because cross joins never match up a column.
In some special cases you'll join on columns where neither is unique. Therefore the presence of a PK/FK on those columns is impossible.
You may think points 2 and 3 above are not relevant since your questions is about when there IS a single PK/FK relationship between tables. However the presence of single PK/FK between the tables does not mean you can't have other fields to join on in addition to the PK/FK. The sql engine would not know which fields you want to join on.
Lets say you have a table "USA_States", and 5 other tables with a FK to the states. The "five" tables also have a few foreign keys to each other. Should the sql engine automatically join the "five" tables with "USA_States"? Or should it join the "five" to each other? Both? You could set up the relationships so that the sql engine enters an infinite loop trying to join stuff together. In this situation it's impossible fore the sql engine to guess what you want.
In summary: PK/FK has nothing to do with table joins. They are separate unrelated things. It's just an accident of nature that you often join on the PK/FK columns.
Would you want the sql engine to guess if it's a full, left, right, or inner join? I don't think so. Although that would arguably be a lesser sin than guessing the columns to join on.