CASE示例涉及正确的邮件名称

时间:2015-04-20 19:45:02

标签: sql oracle loops case

我有以下内容:

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语句,循环正确吗?

前缀是一个单独的字段。 感谢。

1 个答案:

答案 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表达式根本不是。