左多次加入同一个表,只获得每个连接的最大值

时间:2016-01-18 12:18:32

标签: sql

我有以下查询,每个连接返回多行,但我只需要返回id最高的行

如果没有子查询我怎么能​​这样做?

plesk sbin pci_compliance_resolver --enable

返回类似于:

的内容
SELECT cp.RefId, work.PhoneNumber AS work, work.id AS work_id, home.PhoneNumber AS home, home.id AS home_id
FROM Contacts cp
LEFT JOIN OtherPhoneNumber work ON cp.ZoneId = work.ZoneId AND work.PhoneNumber_Type = 'W' AND work.OwnerType = 'C' AND work.OwnerRefId = cp.RefId
LEFT JOIN OtherPhoneNumber home ON cp.ZoneId = home.ZoneId AND home.PhoneNumber_Type = 'H' AND home.OwnerType = 'C' AND home.OwnerRefId = cp.RefId
WHERE cp.ZoneId = '123123'

我只想要:

RefId       work                work_id    home             home_id
QWERTY1234  01234523423         1739092    01234563232      1818181
QWERTY1234  01234523423267196   1739093    01234563232      1818181

3 个答案:

答案 0 :(得分:1)

一种方法是提取家庭和工作号码的ID,然后再加入原始表格:

SELECT cp.RefId, work.PhoneNumber AS work, work.id AS work_id,
       home.PhoneNumber AS home, home.id AS home_id
FROM Contacts cp LEFT JOIN
     (SELECT o..OwnerRefId, o.zoneId,
             MAX(CASE WHEN o..PhoneNumber_Type = 'W' THEN w.id END) as workid,
             MAX(CASE WHEN o..PhoneNumber_Type = 'H' THEN w.id END) as homeid
      FROM OtherPhoneNumber o
      WHERE w.OwnerType = 'C'
      GROUP BY o.OwnerRefId, o..zoneId
     ) wh
     ON cp.RefId = w.OwnerRefId LEFT JOIN
     OtherPhoneNumber work
     ON work.id = wh.workid LEFT JOIN
     OtherPhoneNumber home
     ON home.id = wh.homeid 
WHERE cp.ZoneId = '123123';

编辑:

在SQL Server中,您可以使用OUTER APPLY

执行此操作
select cp.RefId, work.PhoneNumber AS work, work.id AS work_id, 
       home.PhoneNumber AS home, home.id AS home_id
from Contacts cp outer apply
     (select top 1 o.*
      from OtherPhoneNumber o
      where o.PhoneNumber_Type = 'W' AND o.OwnerType = 'C' AND
            o.OwnerRefId = cp.RefId AND o.ZoneId = cp.ZoneId
      order by o.id desc
     ) work outer apply
     (select top 1 o.*
      from OtherPhoneNumber o
      where o.PhoneNumber_Type = 'H' AND o.OwnerType = 'C' AND
            o.OwnerRefId = cp.RefId AND o.ZoneId = cp.ZoneId
      order by o.id desc
     ) home 
where cp.ZoneId = '123123';

这可能是最快的方法,使用正确的索引:Contacts(ZoneId, RefId)OtherPhoneNumber(ZoneId, OwnerRefId, PhoneNumber_Type, OwnerType, id)

答案 1 :(得分:0)

好的,你可以试试这个 -

;WITH myCTE
AS 
(
    SELECT
        cp.RefId
        ,work.PhoneNumber AS work
        ,work.id AS work_id
        ,home.PhoneNumber AS home
        ,home.id AS home_id
        ,ROW_NUMBER() OVER (PARTITION BY cp.RefId, work.PhoneNumber, work.id, home.PhoneNumber, home.id ORDER BY cp.RefId) AS RowNum
    FROM Contacts cp
    LEFT JOIN OtherPhoneNumber work
        ON cp.ZoneId = work.ZoneId
        AND work.PhoneNumber_Type = 'W'
        AND work.OwnerType = 'C'
        AND work.OwnerRefId = cp.RefId
    LEFT JOIN OtherPhoneNumber home
        ON cp.ZoneId = home.ZoneId
        AND home.PhoneNumber_Type = 'H'
        AND home.OwnerType = 'C'
        AND home.OwnerRefId = cp.RefId
    WHERE cp.ZoneId = '123123'
)
SELECT
    *
FROM myCTE
WHERE RowNum = 1

答案 2 :(得分:0)

您可以使用Outer Apply

SELECT cp.RefId, W.work, W.work_id, H.home, H.home_id
    FROM Contacts cp
         Outer Apply 
         (
          Select Top 1  work.Id as work_id, work.PhoneNumber  as work
          From    OtherPhoneNumber work 
          Where  work.ZoneId = cp.ZoneId  AND work.PhoneNumber_Type = 'W' AND work.OwnerType = 'C' AND work.OwnerRefId = cp.RefId
         Order By Work.Id Desc
         ) W
        Outer Apply
        (
         Select Top 1  home.Id as home_id, home.PhoneNumber  as Home
         From OtherPhoneNumber home 
         Where home.ZoneId = cp.ZoneId  AND home.PhoneNumber_Type = 'H' AND home.OwnerType = 'C' AND home.OwnerRefId = cp.RefId
        Order By H.Id Desc
        ) H
    WHERE cp.ZoneId = '123123'