AdventureWorks查询问题:如何关联表获取销售人员完整信息
解决AdventureWorks销售代表信息查询的表关联问题
你的问题出在表关联条件不完整,直接用逗号连接多张表会产生笛卡尔积,而且没有建立Sales.SalesPerson与其他表、Sales.SalesTerritory与Sales.SalesPerson的关联关系,导致结果完全不符合预期。
正确的表关联逻辑
AdventureWorks中这几张表的关联关系是:
Person.Person↔HumanResources.Employee:通过BusinessEntityID关联(每个员工对应一条人员基础信息)HumanResources.Employee↔Sales.SalesPerson:通过BusinessEntityID关联(销售代表属于员工的子类型)Sales.SalesPerson↔Sales.SalesTerritory:通过TerritoryID关联(销售代表对应一个专属销售区域)
修正后的SQL语句
1. 仅返回已分配销售区域的销售代表(INNER JOIN)
SELECT p.FirstName, p.LastName, e.HireDate, e.SickLeaveHours, sp.SalesQuota, st.CountryRegionCode AS 工作区域 FROM Person.Person p INNER JOIN HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID INNER JOIN Sales.SalesPerson sp ON e.BusinessEntityID = sp.BusinessEntityID INNER JOIN Sales.SalesTerritory st ON sp.TerritoryID = st.TerritoryID;
2. 返回所有销售代表(含无配额/未分配区域的记录,LEFT JOIN)
如果存在还未设置销售配额或未分配区域的销售代表,用LEFT JOIN可以保留这些记录,避免被过滤:
SELECT p.FirstName, p.LastName, e.HireDate, e.SickLeaveHours, COALESCE(sp.SalesQuota, 0) AS SalesQuota, -- 可选:将NULL配额转为0 ISNULL(st.CountryRegionCode, '未分配') AS 工作区域 -- 可选:将NULL区域转为"未分配" FROM Person.Person p INNER JOIN HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID INNER JOIN Sales.SalesPerson sp ON e.BusinessEntityID = sp.BusinessEntityID LEFT JOIN Sales.SalesTerritory st ON sp.TerritoryID = st.TerritoryID;
关键优化点
- 用显式
JOIN语法替代逗号连接,关联逻辑更直观,彻底避免笛卡尔积 - 给表设置短别名,简化SQL语句的可读性
- 可通过
COALESCE/ISNULL处理NULL值,让结果更友好
内容的提问来源于stack exchange,提问作者stephen
相关产品推荐
相关产品推荐

