关于正确邮寄名称的 CASE 示例
CASE example when it comes to proper mailing names
我有以下内容:
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
基本遵循规则:
- 夫妻姓氏相同,前缀相同,男的name/info在前。
- 夫妻同姓,大姓在前
- 夫妻不同姓,前缀相等或他大,男name/info在前
- 夫妇姓氏不同,她的前缀更大,她的 name/info 在前。
它本质上是一个 CASE 语句,循环正确吗?
前缀是一个单独的字段。
谢谢
所以是的,一个 CASE
表达式,但我不确定为什么循环会有任何相关性。您是否认为您需要存储过程或其他东西?
最重要的问题似乎是确定哪个配偶排名更高。这可以在辅助 table 的帮助下解决,可能是这样的:
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);
注意排名值之间的差距。留空隙可以让你打破配偶之间的联系,通过在丈夫的排名中添加一个小于空隙大小的常量来支持丈夫。
另请注意,我使用前缀本身作为键,而不是引入代理键。如果您还没有单独的 table 前缀,那么这允许在不重新组织现有 table 和查询的情况下添加排名数据,并且它避免需要加入前缀 table 在您希望将前缀用于邮寄标签以外的任何其他目的时获取前缀。
有了它,您可以像这样查询所需的地址标签 (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
避免重复,并确保 table prim
确实包含每对夫妇中排名较高(主要)的人的信息
- 在到达主查询的 select 列表之前,已经弄清楚哪个是排名较高的配偶,需要
CASE
表达式来选择 assemble 姓名的方式一点都不差。
我有以下内容:
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
基本遵循规则:
- 夫妻姓氏相同,前缀相同,男的name/info在前。
- 夫妻同姓,大姓在前
- 夫妻不同姓,前缀相等或他大,男name/info在前
- 夫妇姓氏不同,她的前缀更大,她的 name/info 在前。
它本质上是一个 CASE 语句,循环正确吗?
前缀是一个单独的字段。 谢谢
所以是的,一个 CASE
表达式,但我不确定为什么循环会有任何相关性。您是否认为您需要存储过程或其他东西?
最重要的问题似乎是确定哪个配偶排名更高。这可以在辅助 table 的帮助下解决,可能是这样的:
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);
注意排名值之间的差距。留空隙可以让你打破配偶之间的联系,通过在丈夫的排名中添加一个小于空隙大小的常量来支持丈夫。
另请注意,我使用前缀本身作为键,而不是引入代理键。如果您还没有单独的 table 前缀,那么这允许在不重新组织现有 table 和查询的情况下添加排名数据,并且它避免需要加入前缀 table 在您希望将前缀用于邮寄标签以外的任何其他目的时获取前缀。
有了它,您可以像这样查询所需的地址标签 (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
避免重复,并确保 tableprim
确实包含每对夫妇中排名较高(主要)的人的信息 - 在到达主查询的 select 列表之前,已经弄清楚哪个是排名较高的配偶,需要
CASE
表达式来选择 assemble 姓名的方式一点都不差。