我使用的是AdvetureWorks数据库。这是我想做的事情: 给我姓氏,名字,公司名称,并列出客户Virginia Miller的所有地址,包括地址类型,地址,城市和州。 您需要将3个表连接在一起并过滤结果。你应该只获得2行。 这就是我到目前为止......
Select
SalesLT.Customer.LastName,
SalesLT.Customer.FirstName,
SalesLT.Customer.CompanyName,
CustomerAddress.AddressType,
SalesLT.Address.AddressLine1,
SalesLT.Address.City,
SalesLT.Address.StateProvince
From SalesLT.Customer C, SalesLT.CustomerAddress CA, SalesLT.Address A
join SalesLT.CustomerAddress
on SalesLT.Address.AddressID=SalesLT.CustomerAddress.AddressID
join SalesLT.Customer
on SalesLT.CustomerAddress.CustomerID=SalesLT.Customer.CustomerID
join SalesLT.Address
on SalesLT.CustomerAddress.AddressID=SalesLT.Address.AddressID
Where SalesLT.Customer.FirstName = 'Virginia'
是的我是新人,不太了解加入。非常感谢任何正确方向的推动!
答案 0 :(得分:1)
我相信以下内容应该可以解决您的问题。
USE SalesLT
SELECT
c.LastName,
c.FirstName,
c.CompanyName,
ca.AddressType,
a.AddressLine1,
a.City,
a.StateProvince
FROM
Customer c
JOIN
CustomerAddress ca
ON c.CustomerID=ca.CustomerID
JOIN
Address a
ON ca.AddressID=a.AddressID
WHERE
c.FirstName = 'Virginia'
AND c.LastName = 'Miller'
构建SQL查询时,我发现最好只从主表中选择我想要的数据。因此,在此查询的情况下,您正在查找有关特定客户的信息(在此示例中,您已经为其提供了Virginia Miller)。因此,只需获取有关该客户的信息,查询就会像这样。
USE SalesLT
SELECT
c.LastName,
c.FirstName
FROM
Customer c
WHERE
c.FirstName = 'Virginia'
AND c.LastName = 'Miller'
所以你在那里完成的工作是通过指示你将使用哪个数据库(即USE SalesLT系列)开始的。这将有助于输入,因此您不必在每个表名之前添加它。
接下来,您将选择您感兴趣的列名(LastName和FirstName)。他们有“c”。在他们面前指定表的昵称或“别名”,我们说SQL可以在中找到该数据。
在“FROM”行中,您可以看到您正在告诉SQL查看Customer表,并且您将为该表提供别名“c”,以便您可以快速引用它并使其清楚哪些列属于查询中的哪些表。
现在您正在为弗吉尼亚米勒获取数据,让我们看看下一篇文章。您需要弗吉尼亚州的地址,因此您需要某种方式将地址数据与客户数据相关联。
幸运的是,AdventureWorks数据库很容易实现,因为它们具有CustomerAddress“join”表。像这样的表被设计为在具有某种类型的ID列的两个表之间简单地链接记录。在这种情况下,它链接CustomerID(Customer表中的一列)和AddressID(Address表中的一列),以便我们可以找出特定客户可能拥有的地址。
所以现在我们知道我们需要来自CustomerAddress的数据,所以我们应该将下一部分添加到我们的查询中。
USE SalesLT
SELECT
c.LastName,
c.FirstName,
c.CompanyName,
ca.AddressType
FROM
Customer c
JOIN
CustomerAddress ca
ON c.CustomerID=ca.CustomerID
WHERE
c.FirstName = 'Virginia'
AND c.LastName = 'Miller'
上面代码中的新部分是添加从CustomerAddress表中选择AddressType,然后告诉SQL Customer表和CustomerAddress表是如何相关的。它可以在它们之间连接记录,因为Customer表中的CustomerID等于CustomerAddress表中的Customer ID(JOIN CustomerAddress ca ON c.CustomerID = ca.CustomerID)。 “ca”是我们为CustomerAddress表提供的昵称或别名,因此我们使用它来在查询中的其他位置引用它。
现在我们已经让查询的那部分工作了,我们已准备好在最后阶段获取实际的地址信息。
USE SalesLT
SELECT
c.LastName,
c.FirstName,
c.CompanyName,
ca.AddressType
FROM
Customer c
JOIN
CustomerAddress ca
ON c.CustomerID = ca.CustomerID
JOIN
Address a
ON a.AddressID = ca.AddressID
WHERE
c.FirstName = 'Virginia'
AND c.LastName = 'Miller'
最后一步只是添加了有关Address表如何与CustomerAddress表相关的附加信息。基本上,CustomerAddress中的AddressID列等于Address中的AddressID列。
现在我们回到原始查询中,包含我们想要的所有信息,表SQL可以找到数据,以及我们在表之间定义的关系。
逐步解决问题通常是一个很好的方法。
答案 1 :(得分:1)
select语句的目的是以特定方式返回一些数据。这大致采用以下形式:
select <columns>
from <table/group of tables joined together/sub-query/tvf etc.>
where <condition>
1 - 现在,你遇到问题的那一点似乎是中间位 - 我们会先这样做。
您有三个表格,其中包含您想要的数据:
SalesLT.Customer
SalesLT.CustomerAddress
SalesLT.Address
并且您希望将它们一起连接到数据彼此相关的列,在本例中为CustomerID。内部连接语句采用以下形式(选择内连接,因为所有条目在其他表中都匹配!):
table1 inner join table2 on table1.columnname = table2.columnname
如果我们将您的示例与此语法匹配,我们就会得到:
SalesLT.CustomerAddress INNER JOIN
SalesLT.Customer ON SalesLT.CustomerAddress.CustomerID = SalesLT.Customer.CustomerID INNER JOIN
SalesLT.Address ON SalesLT.CustomerAddress.AddressID = SalesLT.Address.AddressID
现在,select语句的其余部分将此查询视为数据的一个大“集合”,几乎就像它是一个表一样 - 每个列都由表名预先固定。如果您在语句的其他地方引用其中一个,则并不总是需要包含完全限定的名称(因为只要结果集中的名称不超过一列,就可以猜测。)
2 - 您似乎已经掌握了过滤where子句,但您似乎只是在使用名字进行过滤,尽管您有初步要求。添加一个很容易:
WHERE (SalesLT.Customer.FirstName = 'Virginia') AND (SalesLT.Customer.LastName = N'Miller')
3 - 最后还有一个小问题你想要回来 - 你已经有了正确的答案。
结合我们一起完成的工作,您会得到以下查询:
SELECT SalesLT.Customer.LastName, SalesLT.Customer.FirstName, SalesLT.Customer.CompanyName, SalesLT.CustomerAddress.AddressType,
SalesLT.Address.AddressLine1, SalesLT.Address.City, SalesLT.Address.StateProvince
FROM SalesLT.CustomerAddress INNER JOIN
SalesLT.Customer ON SalesLT.CustomerAddress.CustomerID = SalesLT.Customer.CustomerID INNER JOIN
SalesLT.Address ON SalesLT.CustomerAddress.AddressID = SalesLT.Address.AddressID
WHERE (SalesLT.Customer.FirstName = 'Virginia') AND (SalesLT.Customer.LastName = N'Miller')
答案 2 :(得分:0)
我没有安装Adventure DB,所以我不知道这些关系。假设您提到的关系有效,这应该有效:
USE SalesLT
SELECT
c.LastName,
c.FirstName,
c.CompanyName,
ca.AddressType,
a.AddressLine1,
a.City,
a.StateProvince,
FROM Customer C
INNER JOIN CustomerAddress ca ON ca.CustomerID = c.CustomerID
LEFT JOIN Address a ON a.AddressID = ca.AddressID
WHERE c.FirstName = 'Virginia'
备注 - 我在地址上使用了LEFT JOIN,因为我不知道是否有可能没有地址记录的客户记录。在可能的情况下,即使没有地址,您仍希望为客户提供记录,请使用LEFT JOIN和COALESCE来识别NULL记录。