Sql server SQL-关于“的帮助”;按组分列的前1名”;

Sql server SQL-关于“的帮助”;按组分列的前1名”;,sql-server,tsql,greatest-n-per-group,Sql Server,Tsql,Greatest N Per Group,相关表格: DepartmentPhone:DepartmentPhoneID int,DepartmentID int,PhoneID int 电话:PhoneID int,PhoneType int 有6部PhoneType=4的手机属于DepartmentID=2。这样就产生了6条记录: select * from DepartmentPhone join Phone on Phone.PhoneID = DepartmentPhone.PhoneID and Phone.Phone

相关表格:
DepartmentPhone:DepartmentPhoneID int,DepartmentID int,PhoneID int
电话:PhoneID int,PhoneType int

有6部PhoneType=4的手机属于DepartmentID=2。这样就产生了6条记录:

select *
from DepartmentPhone
  join Phone on Phone.PhoneID = DepartmentPhone.PhoneID and Phone.PhoneType = 4
where DepartmentPhone.DepartmentID = 2
请注意,DepartmentID=2用于说明,我的查询将显示所有部门。
我想要实现的是为每个部门选择第一个电话(type=4),每个部门仅选择一行。我原以为下面的查询可以解决这个问题,但它一直在检索所有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)

谢谢你的帮助

我不象你那样了解你的模式,但我猜你需要通过
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;
选择d1*
部门电话d1
在d1.PhoneID=p1.PhoneID和p1.PhoneType=4上连接电话p1
左侧外部连接(部门电话d2连接电话p2
在d2上。PhoneID=p2。PhoneID和p2。PhoneType=4)
在d1.DepartmentID=d2.DepartmentID和d1.PhoneID
我希望这有一个干净的语法。最好使用
行号

;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

谢谢你的回答。虽然这是正确的,但Bill告诉我我的错误在哪里(与DepartmentPhoneID相关,而不是与DepartmentID相关)。我感谢你的帮助。