相关表格:
DepartmentPhone:DepartmentPhoneID int,DepartmentID int,PhoneID int
电话:PhoneID int,PhoneType int
PhoneType = 4的手机有6部属于DepartmentID = 2。所以这产生了6条记录:
select *
from DepartmentPhone
join Phone on Phone.PhoneID = DepartmentPhone.PhoneID and Phone.PhoneType = 4
where DepartmentPhone.DepartmentID = 2
请注意,DepartmentID = 2仅用于说明目的,我的查询将带来所有部门
我想要实现的是为每个部门选择第一部电话(类型= 4) - 每个部门只有1行。我认为以下查询可以解决问题,但它会继续检索所有6条记录。我错过了什么?
select x.*
from DepartmentPhone x
where
x.DepartmentID = 2
and x.PhoneID = (select max(y.PhoneID)
from departmentphone y
join Phone on y.PhoneID = Phone.PhoneID and Phone.PhoneType = 4
where x.DepartmentPhoneID = y.DepartmentPhoneID)
感谢您的帮助!!!
答案 0 :(得分:2)
我希望 是一个干净的语法。最好的方法是使用ROW_NUMBER
:
;WITH DepartmentPhone_CTE AS
(
SELECT p.*,
ROW_NUMBER() OVER
(PARTITION BY dp.DepartmentID ORDER BY dp.PhoneID) AS RowNum
FROM DepartmentPhone dp
INNER JOIN Phone p
ON p.PhoneID = dp.PhoneID
WHERE p.PhoneType = 4
)
SELECT dp.*
FROM DepartmentPhone_CTE
WHERE RowNum = 1
答案 1 :(得分:0)
我不了解您的架构,但我猜您需要按DepartmentID
关联您的分组,而不是DepartmentPhoneID
。
select x.*
from DepartmentPhone x
where
x.DepartmentID = 2
and x.PhoneID = (select max(y.PhoneID)
from departmentphone y
join Phone on y.PhoneID = Phone.PhoneID and Phone.PhoneType = 4
where x.DepartmentID = y.DepartmentID);
这里有几个替代查询,它们应该在不使用相关子查询的情况下得到相同的结果。第一个使用派生表:
select *
from DepartmentPhone x
join (select d.DepartmentID, max(d.PhoneID) as maxPhoneID
from DpartmentPhone d join Phone p using (PhoneID)
where p.PhoneType = 4
group by d.DepartmentID) y
using (DepartmentID);
第二种方法根本不使用子查询,而是使用自连接:
select d1.*
from DepartmentPhone d1
join Phone p1 on d1.PhoneID = p1.PhoneID and p1.PhoneType = 4
left outer join (DepartmentPhone d2 join Phone p2
on d2.PhoneID = p2.PhoneID and p2.PhoneType = 4)
on d1.DepartmentID = d2.DepartmentID and d1.PhoneID < d2.PhoneID
where d2.DepartmentID is NULL;