DB2 return 第一场比赛
DB2 return first match
在 V6R1 的 DB2 for i (a.k.a.DB2/400) 中,我想写一个 SQL SELECT 语句 returns 来自一个 header 记录和一些来自匹配详细记录的仅一个的列。它可以是任何匹配记录,但我只想要其中一个的信息。我可以使用下面的查询来完成此操作,但我认为必须有比使用 WITH 子句更简单的方法。如果我需要它,我会使用它,但我一直在想,"There must be an easier way"。本质上,我只是从 Person table 返回 firstName 和 lastName ...加上来自 PersonEmail table.
的匹配 email-addresses 之一
谢谢!
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 p1@home.com
2 Tony Iommi p2@cell.com
3 Geezer Butler p3@home.com
4 John Osbourne -
这听起来像是 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;
如果从 PersonEmail 文件中 select 编辑哪一行确实无关紧要,那么就没有理由对该行执行汇总查询或 OLAP 查询select;前者根据 CTE 的 MIN 聚合隐含排序,而后者明确要求排序。以下使用 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
在 V6R1 的 DB2 for i (a.k.a.DB2/400) 中,我想写一个 SQL SELECT 语句 returns 来自一个 header 记录和一些来自匹配详细记录的仅一个的列。它可以是任何匹配记录,但我只想要其中一个的信息。我可以使用下面的查询来完成此操作,但我认为必须有比使用 WITH 子句更简单的方法。如果我需要它,我会使用它,但我一直在想,"There must be an easier way"。本质上,我只是从 Person table 返回 firstName 和 lastName ...加上来自 PersonEmail table.
的匹配 email-addresses 之一谢谢!
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 p1@home.com
2 Tony Iommi p2@cell.com
3 Geezer Butler p3@home.com
4 John Osbourne -
这听起来像是 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;
如果从 PersonEmail 文件中 select 编辑哪一行确实无关紧要,那么就没有理由对该行执行汇总查询或 OLAP 查询select;前者根据 CTE 的 MIN 聚合隐含排序,而后者明确要求排序。以下使用 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