2016-04-19 6 views
2

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

Спасибо!

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      -   

ответ

3

Это звучит как работа для 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; 
+0

Спасибо, @ Гордон-linoff! Это сработало красиво. Ты сильный и талантливый человек! – DaveSlash

+0

@DaveSlash, если этот ответ сработал, не забудьте его пометить. –

3

Если какая строка будет выбираться из файла 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