加入3个表格并过滤SQL
我正在使用AdvetureWorks数据库。这里是我想要做的: 给我的姓氏,名字,公司名称,并列出客户弗吉尼亚米勒的所有地址,包括地址类型,地址,城市和州。 您需要将3个表连在一起并过滤结果。你应该只得到2行。 这是我迄今为止...加入3个表格并过滤SQL
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'
是啊,我新认识不加入很好。任何正确方向的微调都非常感谢!
select语句的要点是以特定的方式返回一些数据。这需要大致有以下几种形式:
select <columns>
from <table/group of tables joined together/sub-query/tvf etc.>
where <condition>
1 - 现在,你已经与有问题的位似乎是中间位 - 我们将做第一个。
你必须包含你想回来的数据三个表:
SalesLT.Customer
SalesLT.CustomerAddress
SalesLT.Address
而且你想将它们连接在一起的,其中数据之间的相互关系,在这种情况下,客户ID列。内部联接语句的形式如下(选择内部连接,因为所有条目具有其他表的一场比赛!):
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')
谢谢!!!!!!这显示了两行要求! – 2012-03-18 03:52:07
对不起,我一直打字输入之前发送的密钥!现在我会回顾一下,真正看到我错过了什么。拥抱你和每个人的真棒帮助! – 2012-03-18 03:53:10
我认为解释和答案可能会帮助你更好地理解它! – Bridge 2012-03-18 03:56:05
我没有安装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记录。
哦,我的!谢谢,我会试试这个。我很新,这很混乱,但我正在练习! – 2012-03-18 03:30:57
不幸的是,这回来了许多红线和一个错误。我不知道联盟是什么。 – 2012-03-18 03:34:40
COALESCE是一个高度使用声明。它只是取第一个非NULL值,因此COALESCE(a.AddressLine1,a.AddressLine2,c.SomeOtherField,'所有这些字段为NULL')将取第一个非空值或输出所有这些字段为NULL。如果你愿意,你可以把COALESCE带走,我通常会把它们放在那里用于左连接,这样我就可以指定在NULL字段值时返回的内容。 – 2012-03-18 03:42:14
我认为以下几点应该解决您的问题。
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查询时,我发现最好从我的主表中选择我想要的数据开始。所以在这个查询的情况下,你正在寻找关于某个特定客户的信息(在这个例子中你已经给出了它的弗吉尼亚米勒)。所以只要获得关于该客户的信息,查询就会像这样。
USE SalesLT
SELECT
c.LastName,
c.FirstName
FROM
Customer c
WHERE
c.FirstName = 'Virginia'
AND c.LastName = 'Miller'
所以,你做了什么有开始以表示你将要使用的数据库(这是USE SalesLT线)。这将有助于打字,因此您无需在每个表名称前添加它。
接下来,您正在选择您感兴趣的列名(姓氏和名字)。他们有“c”。在他们面前指定表格的昵称或“别名”,我们说SQL可以找到该数据。
在“FROM”行中,您可以看到您告诉SQL查看客户表,并且您将为该表提供“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表中选择地址类型,然后告诉SQL如何Customer表和CustomerAddress表中相关的。它可以在它们之间加入记录,因为Customer表中的CustomerID等于CustomerAddress表中的客户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可以找到该数据以及我们在这些表之间定义的关系。
一步步解决问题通常是一个好方法。
谢谢,我会尽力回复。这是一个很棒的网站。 – 2012-03-18 03:37:19
一切都在它下面有一条红线,我得到这个错误... – 2012-03-18 03:39:12
消息208,级别16,状态1,行1 无效的对象名称'客户'。 – 2012-03-18 03:39:21
你的“发件人”行应该只有一个表中列出。“连接”行是告诉SQL你想从中获取信息的附加表。 那到底是什么问题?你解释了你想要的,但不是你尝试了什么,或者你有什么错误或问题。 – 2012-03-18 03:15:14
对不起,我得到了太多的行,我只能从查询中得到2个结果。我有这个可怕的时间,并试图让理智。 – 2012-03-18 03:21:17
查询看起来是正确的,列出的行如选择下的所有行。我希望那是从它的方式?为了显示我在查询中需要什么?这是连接表的作用吗?对不起,我很困惑,但是非常感谢你帮助我。 – 2012-03-18 03:24:17