2012-03-18 104 views
0

我正在使用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' 

是啊,我新认识不加入很好。任何正确方向的微调都非常感谢!

+0

你的“发件人”行应该只有一个表中列出。“连接”行是告诉SQL你想从中获取信息的附加表。 那到底是什么问题?你解释了你想要的,但不是你尝试了什么,或者你有什么错误或问题。 – 2012-03-18 03:15:14

+0

对不起,我得到了太多的行,我只能从查询中得到2个结果。我有这个可怕的时间,并试图让理智。 – 2012-03-18 03:21:17

+0

查询看起来是正确的,列出的行如选择下的所有行。我希望那是从它的方式?为了显示我在查询中需要什么?这是连接表的作用吗?对不起,我很困惑,但是非常感谢你帮助我。 – 2012-03-18 03:24:17

回答

1

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') 
+0

谢谢!!!!!!这显示了两行要求! – 2012-03-18 03:52:07

+0

对不起,我一直打字输入之前发送的密钥!现在我会回顾一下,真正看到我错过了什么。拥抱你和每个人的真棒帮助! – 2012-03-18 03:53:10

+0

我认为解释和答案可能会帮助你更好地理解它! – Bridge 2012-03-18 03:56:05

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记录。

+0

哦,我的!谢谢,我会试试这个。我很新,这很混乱,但我正在练习! – 2012-03-18 03:30:57

+0

不幸的是,这回来了许多红线和一个错误。我不知道联盟是什么。 – 2012-03-18 03:34:40

+0

COALESCE是一个高度使用声明。它只是取第一个非NULL值,因此COALESCE(a.AddressLine1,a.AddressLine2,c.SomeOtherField,'所有这些字段为NULL')将取第一个非空值或输出所有这些字段为NULL。如果你愿意,你可以把COALESCE带走,我通常会把它们放在那里用于左连接,这样我就可以指定在NULL字段值时返回的内容。 – 2012-03-18 03:42:14

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查询时,我发现最好从我的主表中选择我想要的数据开始。所以在这个查询的情况下,你正在寻找关于某个特定客户的信息(在这个例子中你已经给出了它的弗吉尼亚米勒)。所以只要获得关于该客户的信息,查询就会像这样。

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可以找到该数据以及我们在这些表之间定义的关系。

一步步解决问题通常是一个好方法。

+0

谢谢,我会尽力回复。这是一个很棒的网站。 – 2012-03-18 03:37:19

+0

一切都在它下面有一条红线,我得到这个错误... – 2012-03-18 03:39:12

+0

消息208,级别16,状态1,行1 无效的对象名称'客户'。 – 2012-03-18 03:39:21