在一个查询中选择不同的子类型值

时间:2019-09-24 07:30:15

标签: sql oracle subtype

我对oracle和处理子类型是陌生的。我需要选择一个MP3_TYPE专辑和DISK_TYPE中MEDIA_TYPE的两个值:乙烯基,音频CD。

这是创建子类型查询:

create or replace type disk_type under album_type 
( mediaType         varchar(10),
  diskNum           number(2), -- number of disks
  diskUsedPrice     number(9,2),
  diskDeliveryCost  number(9,2), 
  overriding member function discountPrice return number)
/
create or replace type mp3_type under album_type
(downloadSize   number, -- size in MB
overriding member function discountPrice return number)
/

我可以分别选择所有3种类型,但是当所有3种都在一个查询中时,它似乎不起作用。对于treat函数来说不是很好,因此假设这是一些语法问题。

这是我所做的:

select
    t1.albumtitle
from albums t1
where value(t1) IS OF (mp3_type) 
    and treat(value(t1) as disk_type).mediatype = 'Vinyl'
    and treat(value(t1) as disk_type).mediatype = 'Audio CD';

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

在到目前为止显示的代码中,mp3_typedisk_type都是album_type的子类型。这似乎是合理的。但这意味着表中的单个对象不能同时是两个子类型。因此它不能同时具有两个子类型的属性。

如果一行是mp3_type,则将其视为disk_type不会导致设置disk_type属性。当您将该对象视为disk_type时,这些属性将-必须为-null。

insert into albums values (album_type('ABC'));
insert into albums values (mp3_type('BCD', 123));
insert into albums values (disk_type('DEF', 'Vinyl', 1, 12.34, 1.23));

select
    t1.albumtitle
from albums t1
where value(t1) IS OF (mp3_type) 
    and treat(value(t1) as disk_type).mediatype = 'Vinyl'
    and treat(value(t1) as disk_type).mediatype = 'Audio CD';

no rows selected

select
    t1.albumtitle,
    treat(value(t1) as disk_type).mediatype
from albums t1
where value(t1) IS OF (mp3_type);

ALBUMTITLE                     TREAT(VALU
------------------------------ ----------
BCD                                      
  

我需要选择一个MP3_TYPE和DISK_TYPE中两个MEDIA_TYPE值的专辑:乙烯基,音频CD

如果为MP3_TYPE,则MEDIA类型为null;但是即使使用disk_type条目,媒体类型也不能同时是 Velyl和CD。

也许您只是说或使用or而不是and

select
    t1.albumtitle,
    treat(value(t1) as mp3_type).downloadsize as downloadsize,
    treat(value(t1) as disk_type).mediatype as mediatype
from albums t1
where
    value(t1) IS OF (mp3_type) 
    or (
        value(t1) IS OF (disk_type)
        and (
            treat(value(t1) as disk_type).mediatype = 'Vinyl'
            or treat(value(t1) as disk_type).mediatype = 'Audio CD'
        )
    );

ALBUMTITLE                     DOWNLOADSIZE MEDIATYPE 
------------------------------ ------------ ----------
BCD                                     123           
DEF                                         Vinyl