Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql oracle:当类型不存在时获取空值_Sql_Oracle - Fatal编程技术网

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。我做了一些改变,得到了所有可能的类型,如: