DB2 возвращает первое совпадение

В DB2 for i (также известной как DB2/400) версии V6R1 я хочу написать оператор SQL SELECT, который возвращает несколько столбцов из записи заголовка и несколько столбцов из ТОЛЬКО ОДНОЙ из соответствующих записей сведений. Это может быть ЛЮБАЯ совпадающая запись, но мне нужна информация только от ОДНОЙ из них. Я могу выполнить это с помощью следующего запроса ниже, но я думаю, что должен быть более простой способ, чем использование предложения WITH. Я буду использовать его, если мне это нужно, но я продолжаю думать: «Должен быть более простой способ». По сути, я просто возвращаю имя и фамилию из таблицы Person... плюс ОДИН из соответствующих адресов электронной почты из таблицы PersonEmail.

Спасибо!

    with theMinimumOnes as (
    select personId,
           min(emailType) as emailType  
      from PersonEmail
     group by personId
    )
    select p.personId,
           p.firstName,
           p.lastName,
           pe.emailAddress
      from Person p
      left outer join theMinimumOnes tmo
        on tmo.personId = p.personId
      left outer join PersonEmail pe
        on pe.personId = tmo.personId
       and pe.emailType  = tmo.emailType

    PERSONID   FIRSTNAME                       LASTNAME                        EMAILADDRESS
           1   Bill                            Ward                            [email protected] 
           2   Tony                            Iommi                           [email protected] 
           3   Geezer                          Butler                          [email protected] 
           4   John                            Osbourne                        -           

person Dave Ford    schedule 19.04.2016    source источник


Ответы (2)


Похоже, это работа для row_number():

select p.personId, p.firstName, p.lastName, pe.emailAddress
from Person p left outer join
     (select pe.*,
             row_number() over (partition by personId order by personId) as seqnum
      from PersonEmail pe
     ) pe
     on pe.personId = tmo.personId and seqnum = 1;
person Gordon Linoff    schedule 19.04.2016
comment
Спасибо, @gordon-linoff! Это сработало прекрасно. Ты сильный и талантливый человек! - person Dave Ford; 20.04.2016
comment
@DaveSlash, если этот ответ сработал, не забудьте отметить его. - person Tracy Probst; 21.04.2016

Если действительно неважно, какая строка будет выбрана из файла PersonEmail, то нет особых причин выполнять либо сводный запрос, либо запрос OLAP для выбора этой строки; В первом случае порядок подразумевается в соответствии с агрегатом MIN CTE, а во втором порядок запрашивается явно. Следующее использование предложения FETCH FIRST должно быть достаточным, без каких-либо требований для ORDER данных во вторичном файле [просто любая совпадающая строка; хотя, вероятно, будет первым или последним, в зависимости от ключей personId, хотя полностью зависит от реализации запроса, которая может быть даже без использования ключа]:

  select p.personId, p.firstName, p.lastName 
       , pe.emailAddress 
  from Person as p 
  left outer join lateral 
     ( select pe.* 
       from PersonEmail pe 
       where pe.personId = p.personId 
       fetch first 1 row only 
     ) as pe 
  on p.personId = pe.personId 
person CRPence    schedule 11.05.2016