我目前有user_addresses
表:
id | name | address_type | address
---+------+--------------+----------
1 | John | HOME | home addr
1 | John | MAIL | mail addr
2 | Bill | HOME | home addr
3 | Rick | HOME | home addr
3 | Rick | MAIL | mail addr
我想构建一个使用user_addresses
表中数据的新视图。 address_type=MAIL
时,应在address
字段中使用其邮箱地址。否则,它会使用home
地址:
id | name | address_type | address | data from other tables
---+------+--------------+-----------+-----------------------
1 | John | MAIL | mail addr |
2 | Bill | HOME | home addr |
3 | Rick | MAIL | mail addr |
我目前正在展平user_addresses
表,因此用户只有一行,并且他们在自己的列中拥有主页/邮件地址。然后我从这个新的扁平视图中选择并做一个案例陈述:
case when mail_address is not null then mail_address else home_address end
我应该使用max(case when)
,工会/减号还是别的什么?实现这个目标的最佳方法是什么?
答案 0 :(得分:1)
解决此问题的一种方法是使用“邮件”记录获取所有ID,然后将所有ID的所有“主”记录带到没有“邮件”记录的位置:
select ua.*
from user_addresses us
where address_type = 'MAIL'
union all
select ua.*
from user_addresses ua
where address_type = 'HOME' and
not exists (select 1
from user_addresses ua2
where ua2.id = ua.id and ua2.address_type = 'MAIL'
);
另一种方法是使用row_number()
确定行的优先级:
select ua.*
from (select ua.*,
row_number() over (partition by id order by (case when address_type = 'MAIL' then 1 else 2 end)) as seqnum
from user_addresses ua
) ua
where seqnum = 1;
答案 1 :(得分:1)
使用窗口函数:
create or replace view v
as
with cte as
(
select id , name , address_type , address,
row_number() over(partition by id order by address_type desc) rn
from your_table
)
select id , name , address_type , address from cte where rn=1;
答案 2 :(得分:1)
不使用PIVOT的任何特殊原因?
Oracle 11g R2架构设置:
CREATE TABLE t
("id" int, "name" varchar2(4), "address_type" varchar2(4), "address" varchar2(9))
;
INSERT ALL
INTO t ("id", "name", "address_type", "address")
VALUES (1, 'John', 'HOME', 'home addr')
INTO t ("id", "name", "address_type", "address")
VALUES (1, 'John', 'MAIL', 'mail addr')
INTO t ("id", "name", "address_type", "address")
VALUES (2, 'Bill', 'HOME', 'home addr')
INTO t ("id", "name", "address_type", "address")
VALUES (3, 'Rick', 'HOME', 'home addr')
INTO t ("id", "name", "address_type", "address")
VALUES (3, 'Rick', 'MAIL', 'mail addr')
SELECT * FROM dual
;
查询1 :
with flat as (
select * from t
pivot(
max("address")
for "address_type" in ('HOME' as home,'MAIL' as mail)
)
)
select "id","name",coalesce(mail, home) as address
from flat
<强> Results 强>:
| id | name | ADDRESS |
|----|------|-----------|
| 2 | Bill | home addr |
| 3 | Rick | mail addr |
| 1 | John | mail addr |
P.S。忽略双引号标识符 - 懒得修复sqlfiddle的text-to-ddl解析器输出:)