SQL Server中的Join和Select Top 1

4

我有一个客户表和一个地址表。每个客户在地址表中应该有多个地址,我需要一个存储过程来选择一个客户的详细信息和他在地址表中的顶部地址。选择客户的参数是companyID。

SELECT top 1  s.Addr1 as ShipAddress_Addr1,s.Addr2 as  ShipAddress_Addr2,s.Addr3 as ShipAddress_Addr3,
    s.Addr4 as ShipAddress_Addr4,s.Addr5 as ShipAddress_Addr5,
    s.City as ShipAddress_City,s.[state] as ShipAddress_State,s.PostalCode as ShipAddress_PostalCode,
    s.Country as ShipAddress_Country,s.Note as ShipAddress_Note ,c.CustomerID,c.[TimeCreated], c.[FullName],c.FirstName,c.LastName,c.Phone, c.Email, 
    c.BillAddress_Addr1, c.[BillAddress_Addr2],c. [BillAddress_Addr3],c. [BillAddress_Addr4],c.[BillAddress_Addr5],
     c.BillAddress_City,c.BillAddress_State,c.BillAddress_PostalCode,c.BillAddress_Country,c.BillAddress_Note
        FROM   Customer c left join [dbo].[CustomerShipToAddress] s on s.customerListID=c.CustomerID    
    WHERE c.IsActive = 1 and c.CompanyID = @CompanyID

1
在提问之前,你尝试过什么了吗? - Ilyes
看一下CROSS APPLYTOP。 请先自己尝试,如果不成功,请发布您的尝试,我们可以向您展示您哪里错了。 - Thom A
请注意,“top 1”将是无意义的/随机的,除非您在地址表的有用列上指定ORDER BY。 - Peter B
2个回答

11

您可以像这样使用outer apply为每个客户应用最新的地址:

select c.customerid, c.name, c.accno, c.txnid, ta.add1, ta.add2
from customertable c
outer apply (select top 1 a.add1, a.add2 from addresstable a where a.customerid = c.customerid order by a.addressid desc) ta

外部应用程序中的子查询对于每个客户将始终返回0或1行,因此当您与 customertable 连接时,它不会导致行的重复。


-2
SELECT TOP 1, c.customerid, c.name, a.add1  FROM customertable c, addresstable a WHERE c.customerid == a.customerid 

这将基本上返回第一行。这是你所要求的,但我认为不是你的意思。

如果你想查找特定客户的信息,请使用

SELECT TOP 1, c.customerid, c.name, a.add1  FROM customertable c, addresstable a WHERE c.customerid == a.customerid AND c.customerid == "yourcustomerid"

或者甚至更好

SELECT c.customerid, c.name, DISTINCT a.add1  FROM customertable c, addresstable a WHERE c.customerid == a.customerid 

这个查询不会返回没有地址的客户。即使有多个客户,它也只会返回一行。而第三个查询甚至不是有效的T-SQL。 - Andrey Nikolov
@AndreyNikolov 我知道,我已经在编辑我的答案了。然而,这就是OP所问的。你不能因为问题的表述方式责怪我。 - Daan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接