sql oracle:当类型不存在时获取空值
我有一个带有这些值的表sql oracle:当类型不存在时获取空值,sql,oracle,Sql,Oracle,我有一个带有这些值的表phone emplid type phone 1 HOME 23452 2 HOME 15284 2 BUSN 25523 3 HOME 26542 我要每个雇员都有他的家和电话。当他没有BUSN电话时,它必须为空。因此,我的结果必须是: emplid type phone 1 HOME 23452 2 HOME 15284 2 BUS
phone
emplid type phone
1 HOME 23452
2 HOME 15284
2 BUSN 25523
3 HOME 26542
我要每个雇员都有他的家和电话。当他没有BUSN电话时,它必须为空。因此,我的结果必须是:
emplid type phone
1 HOME 23452
2 HOME 15284
2 BUSN 25523
3 HOME 26542
1 BUSN null
3 BUSN null
我试图加入一个虚拟的桌子
(select 'HOME'as typ from dual
union select 'HOM2' from dual )
但它并没有给我想要的结果。我不知道如何将它与我的
手机
表连接起来,但您尝试的方法是正确的。只是另一张桌子
SELECT PhoneTypes.EmplID, PhoneTypes.Type, Phone
FROM Phone
RIGHT OUTER JOIN (SELECT Distinct emplid, T.Type FROM Phone, (select 'HOME' FROM DUAL as type union select 'HOM2' FROM DUAL union select 'BUSN' FROM DUAL) T) PhoneTypes
ON Phone.type=PhoneTypes.Type
像这样试试。我认为这与你的做法相似
select t.* from Phone t
left outer join
(
select 'HOME'as typ from dual
union select 'HOM2' from dual ) t2
on typ = type
您需要获取所有可能的
emplid
值,并与所有可能的类型
值交叉连接,然后使用外部连接查看哪些值实际存在
例如,如果您想完全基于电话
表中的其他数据,可以使用内联视图获取前两列的不同值:
-- CTE for your sample data
with phone (emplid, type, phone) as (
select 1, 'HOME', 23452 from dual
union all select 2, 'HOME', 15284 from dual
union all select 2, 'BUSN', 25523 from dual
union all select 3, 'HOME', 26542 from dual
)
-- actual query
select e.emplid, t.type, p.phone
from (select distinct emplid from phone) e
cross join (select distinct type from phone) t
left join phone p on p.emplid = e.emplid and p.type = t.type;
EMPLID TYPE PHONE
---------- ---- ----------
1 HOME 23452
2 HOME 15284
2 BUSN 25523
3 HOME 26542
3 BUSN
1 BUSN
但是您可能真的想从(比如)雇员表中获取可能的emplid
值——在这种情况下,您会看到所有雇员的空值,即使他们根本没有电话记录;您可能希望从其他一些表中获取可能的类型
值,或者对列表进行硬编码:
select e.emplid, t.type, p.phone
from (select distinct emplid from phone) e -- or more likely from a separate employee table
cross join (select 'HOME' as type from dual union all select 'HOM2' from dual) t
left join phone p on p.emplid = e.emplid and p.type = t.type;
EMPLID TYPE PHONE
---------- ---- ----------
1 HOME 23452
2 HOME 15284
3 HOME 26542
1 HOM2
2 HOM2
3 HOM2
我一直坚持使用您使用的
'HOM2'
值,即使您的示例数据中根本没有这个值;但是,正如您所看到的,所有员工ID的名称也会出现空条目。许多版本之前,Oracle引入了分区的外部联接就是为了解决这种问题
您确实需要包含各种类型的表。或者,正如您所尝试的,您可以动态创建它。此外,您还需要外部联接的“partition”子句。它在下面代码的所有大写字母中显示(因此可以很容易地找到)
作为一个独立且不相关的事情,在我创建的“helper”子查询中,我还创建了一个ORD列,用于排序。仅当您希望在主查询中始终在BUSN编号之前显示HOME编号时,才需要此选项。当然,还有其他方法可以实现相同的结果,但是因为我们无论如何都要创建一个帮助器子查询,所以我们基本上不需要额外的成本就可以得到它
with
phone(emplid, type, phone) as (
select 1, 'HOME', 23452 from dual union all
select 2, 'HOME', 15284 from dual union all
select 2, 'BUSN', 25523 from dual union all
select 3, 'HOME', 26542 from dual
)
-- end of sample data (for testing only, not part of the actual query)
select p.emplid, h.type, p.phone
from (
select 'HOME' as type, 1 as ord from dual union all
select 'BUSN' , 2 from dual
) h
left outer join phone p PARTITION BY (EMPLID)
on h.type = p.type
order by p.emplid, h.ord
;
EMPLID TYPE PHONE
---------- ---- ----------
1 HOME 23452
1 BUSN
2 HOME 15284
2 BUSN 25523
3 HOME 26542
3 BUSN
试试这个
with
phone as (
select 1 as emplid, 'HOME' as type, '23452' as phone from dual union
select 2, 'HOME', '15284' from dual union
select 2,'BUSN','25523' from dual union
select 3,'HOME','26542' from dual),
types as (
select distinct type from phone
)
select phone.emplid, types.type, phone.phone
from types
left join phone partition by (emplid)
on phone.type = types.type
一个选项是将逻辑与
不在一起使用
with phone(emplid, type, phone) as
(
select 1, 'HOME', 23452 from dual union all
select 2, 'HOME', 15284 from dual union all
select 2, 'BUSN', 25523 from dual union all
select 3, 'HOME', 26542 from dual
)
select * from phone
union all
select emplid, 'BUSN', null
from phone
where emplid not in
( select emplid
from phone p
where type = 'BUSN'
and p.emplid = emplid );
EMPLID TYPE PHONE
------ ---- -----
1 HOME 23452
2 HOME 15284
2 BUSN 25523
3 HOME 26542
3 BUSN NULL
1 BUSN NULL
当您尝试获取“BUSN”时,是否确实尝试使用第二个值为“HOM2”的虚拟表进行连接?我看不出有什么理由这样做,不管其他什么。还有,你有一个表phone
,里面有一列phone
?这可能不会违反任何正式规则,但几乎肯定会导致混乱(和bug);有人可以推测,在这种情况下,OP也会希望将HOME number显示为NULL。我做了一些改变,得到了所有可能的类型,如: