我有以下内容:
Primary Spouse
Mr. James Watson Mrs. Emily Watson
Dr. Janet Snow Mr. Todd Snow
Dr. Ben Moody Dr. Sarah Farmer
Hon. Ann Lilly Dr. Gary Pillars
我希望结果如下:
Combined Mailing Name
Mr. and Mrs. James Watson
Dr. Janet Snow and Mr. Todd Snow
Dr. Ben Moody and Dr. Sarah Farmer
Hon. Ann Lilly and Dr. Gary Pillars
基本遵守规则:
它本质上是一个CASE语句,循环正确吗?
前缀是一个单独的字段。 感谢。
答案 0 :(得分:1)
是的,一个CASE
表达式,但我不确定为什么循环会有任何相关性。您是否认为需要存储过程或其他什么?
最重要的问题似乎是确定哪个配偶的排名较高。这可以通过辅助表来解决,可能是这样的:
create table prefix_rank (
prefix varchar(4) primary key,
rank int
);
insert into prefix_rank values ('Mr.', 10);
insert into prefix_rank values ('Mrs.', 10);
insert into prefix_rank values ('Dr.', 20);
insert into prefix_rank values ('Hon.', 30);
注意排名值之间的差距。留下空白可以让你通过在丈夫队伍中增加一个小于间隙大小的常数来打破配偶之间的关系,有利于丈夫。
另请注意,我使用前缀本身作为键,而不是引入代理键。如果您还没有单独的前缀表,那么这允许添加排名数据而无需重新组织现有的表和查询,并且它可以避免需要加入前缀表以获取前缀,当您希望它们用于任何其他目的不是邮寄标签。
有了这些,您可以查询所需的地址标签(fiddle):
with ranked_person as (
select p.*, (pr.rank + (case p.gender WHEN 'M' THEN 5 ELSE 0 END)) AS rank
from person p join prefix_rank pr on p.prefix = pr.prefix
)
select
prim.id,
case
when sec.id IS NULL then
prim.prefix || ' ' || prim.first_name || ' ' || prim.last_name
when (prim.last_name = sec.last_name and sec.prefix = 'Mrs.') then
prim.prefix || ' and ' || sec.prefix || ' '
|| prim.first_name || ' ' || prim.last_name
else
prim.prefix || ' ' || prim.first_name || ' ' || prim.last_name || ' and ' ||
sec.prefix || ' ' || sec.first_name || ' ' || sec.last_name
end as mailing_name
from
ranked_person prim
left join ranked_person sec on sec.id = prim.spouse_id
where
prim.rank > COALESCE(sec.rank, 0)
;
需要注意的其他事项:
prim.rank > sec.rank
可避免重复,并确保表prim
确实包含每对夫妇排名较高(主要)人的信息CASE
表达式根本不是。