每个客户只返回1个地址

时间:2012-12-03 08:02:51

标签: sql-server tsql

我需要查询前500名客户(最佳买家)的地址。许多公司都有多个地址。

包含数据的表格:

  • CustomerInfo
  • CustomerAddress
  • TransactionInfo
  • TransactionElements

我的查询看起来像这样:

select Customername, CustomerStreet --etc 
from CustomerInfo 
join CustomerAddress on CustomerID = Add_CustID
join  TransactionInfo on Trn_CustID = CustomerID
JOIN TransactionElements ON Trn_CustID = TrE_CustID


GROUP BY CustomerName, CustomerStreet --etc
ORDER BY SUM (TrE_TranValue) DESC

它返回一个公司的多个地址,我只需要一个。

3 个答案:

答案 0 :(得分:1)

如果你使用的是SQL Server 2005及更新版本(在这方面你不够具体),一种方法是使用CTE(公用表表达式)。

使用此CTE,您可以按照某些条件对数据进行分区 - 即CustomerId - 并为每个“分区”提供从1开始的所有行的SQL Server编号,按某些条件排序。

所以尝试这样的事情:

;WITH CustomerAndAddress AS
(
   SELECT 
       c.Customername, ca.CustomerStreet ,
       ROW_NUMBER() OVER(PARTITION BY c.CustomerId ORDER BY ca.AddressID DESC) AS 'RowNum'
   FROM 
       dbo.CustomerInfo c
   INNER JOIN 
       dbo.CustomerAddress ca ON c.CustomerID = ca.Add_CustID       
   WHERE
      ......
)
SELECT 
   Customername, CustomerStreet 
FROM 
   CustomerAndAddress
WHERE
   RowNum = 1

在这里,我只选择每个“分区”的“第一个”条目(即每个CustomerId) - 按某些条件排序(我只是从地址中任意选择AddressID - 适应为你需要在你的CTE中定义。

这会接近你想要的吗?

答案 1 :(得分:1)

这样的东西可以在sql server 2005+上运行。我还建议在表中添加一些别名并引用它们。

select CI.Customername, CA.CustomerStreet --etc 
from CustomerInfo CI
cross apply 
(select top 1 Customername, CustomerStreet --etc
from CustomerAddress where CustomerID = CI.Add_CustID) CA
join  TransactionInfo TI on TI.Trn_CustID = CI.CustomerID
JOIN TransactionElements ON CI.CustomerID = TE.TrE_CustID
GROUP BY CustomerName, CustomerStreet --etc
ORDER BY SUM (TrE_TranValue) DESC

答案 2 :(得分:0)

如果CustomerInfo有多个CustomerAddress,则此查询会为每个CustomerInfo(笛卡尔积)返回CustomerAddress

join CustomerAddress on CustomerID = Add_CustID

因此,如果您只需要获取一个地址,则必须添加选择单CustomerAddress所需的条件:

join CustomerAddress on CustomerID = Add_CustID where <conditions>