2017-10-11 85 views
1

我在表中创建VARRAY(下) 我想查询标题是否具有特定的主题,例如。显示“行动”游戏。 我不知道如何去这个...如何查找VARRAY中是否存在值

CREATE OR REPLACE TYPE Theme_Game AS OBJECT 
(Theme VARCHAR(20)); 
/
CREATE OR REPLACE TYPE Theme_Type AS VARRAY(3) OF Theme_Game; 
/
CREATE OR REPLACE TYPE Game_Type AS OBJECT 
(Title VARCHAR2(50), 
GameTheme Theme_Type); 
/
CREATE TABLE Game_Table of Game_Type 
/
INSERT INTO Game_Table 
VALUES('Star Wars' ,(Theme_Type(Theme_Game('Action'), Theme_Game('FPS')))) 
/

回答

1

您需要使用table()功能揭露嵌套表在FROM子句中。然后,您可以参考集合的属性:

SQL> select g.title 
    2 from game_table g 
    3  , table(g.gametheme) gt 
    4 where gt.theme = 'Action'; 

TITLE 
-------------------------------------------------- 
Star Wars 

SQL> 

“如果我再需要检索与多个主题即动作,FPS行?”

抱歉,笨重的解决方案,但我需要现在去工作。我稍后可能会发布更优雅的解决方案。

SQL> select * from game_table 
    2/

TITLE 
-------------------------------------------------- 
GAMETHEME(THEME) 
-------------------------------------------------------------------------------- 
Star Wars 
THEME_TYPE(THEME_GAME('Action'), THEME_GAME('FPS')) 

Uncharted 3 
THEME_TYPE(THEME_GAME('Action'), THEME_GAME('Puzzle')) 

Commander Cody 
THEME_TYPE(THEME_GAME('Fun'), THEME_GAME('Puzzle')) 


SQL> select g.title 
    2 from game_table g 
    3  , table(g.gametheme) gt 
    4  , table(g.gametheme) gt1 
    5 where gt.theme = 'Action' 
    6 and gt1.theme = 'FPS' ; 

TITLE 
-------------------------------------------------- 
Star Wars 

SQL> 

这种替代方法不会与您的当前类型的工作,因为VARRAY不支持member of。但是如果这个集合是一个嵌套表,它将会工作。

select g.title 
    from game_table g 
    where 'Action' member of g.gametheme 
    and 'FPS' member of g.gametheme 
+0

这个声明是有效的,但是如果我然后需要检索具有多个主题的行,例如Action,FPS呢? – lesovren

+1

@APC如果他需要有两个主题的标题,他将无济于事。然后使用'intersect'。 –

+0

我试图在这种情况下使用'AND'我试图检索既是行动和FPS行,但它不返回任何行。 – lesovren

0

对于多个主题,您可以做类似

select g.Title 
from game_table g, table(g.gameTheme) t 
where t.Theme in ('FPS','Action') 
group by g.Title having count(0) = 2; 

这也可以让你做的事情一样获得技术职称正好n个匹配,至少n个匹配,最多n相匹配......

0

你可以使用一个集合,然后比较使用SUBMULTISET操作多个项目:

SQL Fiddle

的Oracle 11g R2架构设置

CREATE OR REPLACE TYPE Theme_Game AS OBJECT 
(Theme VARCHAR(20)); 
/
CREATE OR REPLACE TYPE Theme_Type AS TABLE OF Theme_Game; 
/
CREATE OR REPLACE TYPE Game_Type AS OBJECT(
    Title VARCHAR2(50), 
    GameTheme Theme_Type 
); 
/
CREATE TABLE Game_Table of Game_Type 
NESTED TABLE GameTheme STORE AS GameTheme_Tab 
/
INSERT INTO Game_Table 
VALUES('Star Wars' ,(Theme_Type(Theme_Game('Action'), Theme_Game('FPS')))) 
/

查询1

SELECT * 
FROM game_table 
WHERE Theme_Type(Theme_Game('Action'), Theme_Game('FPS')) 
     SUBMULTISET OF GameTheme 

Results

|  TITLE |            GAMETHEME | 
|-----------|-------------------------------------------------------| 
| Star Wars | [email protected],[email protected] | 

然而,为什么为Y ou使用Theme_Game对象时,它只有一个VARCHAR2属性?你可以只使用一个VARRAY(3) OF VARCHAR2(20)TABLE OF VARCHAR2(20)没有中间对象:

SQL Fiddle

的Oracle 11g R2架构设置

CREATE OR REPLACE TYPE Varchar20List AS TABLE OF VARCHAR2(20); 
/
CREATE OR REPLACE TYPE Game_Type AS OBJECT(
    Title VARCHAR2(50), 
    GameTheme Varchar20List 
); 
/
CREATE TABLE Game_Table of Game_Type 
NESTED TABLE GameTheme STORE AS GameTheme_Tab 
/
INSERT INTO Game_Table 
VALUES('Star Wars' , Varchar20List('Action', 'FPS')) 
/

查询1

SELECT * 
FROM game_table 
WHERE Varchar20List('Action','FPS') 
     SUBMULTISET OF GameTheme 

Results

|  TITLE | GAMETHEME | 
|-----------|------------| 
| Star Wars | Action,FPS | 

如果你想与VARRAY s到做到这一点,那么:

SQL Fiddle

的Oracle 11g R2架构设置

CREATE OR REPLACE TYPE Varchar20List AS VARRAY(3) OF VARCHAR2(20); 
/
CREATE OR REPLACE TYPE Game_Type AS OBJECT(
    Title VARCHAR2(50), 
    GameTheme Varchar20List 
); 
/
CREATE TABLE Game_Table of Game_Type 
/
INSERT INTO Game_Table 
VALUES('Star Wars' , Varchar20List('Action', 'FPS')) 
/

查询1

SELECT * 
FROM game_table g 
WHERE 2 >= (SELECT COUNT(*) 
       FROM TABLE(g.GameTheme) a 
        INNER JOIN 
        TABLE(Varchar20List('Action', 'FPS')) b 
        ON (a.COLUMN_VALUE = b.COLUMN_VALUE) 
      ) 

Results

|  TITLE | GAMETHEME | 
|-----------|------------| 
| Star Wars | Action,FPS | 

或:

查询2

SELECT * 
FROM game_table g 
WHERE 2 >= (SELECT COUNT(*) 
       FROM TABLE(g.GameTheme) a 
       WHERE a.COLUMN_VALUE IN ('Action', 'FPS') 
      ) 

Results

|  TITLE | GAMETHEME | 
|-----------|------------| 
| Star Wars | Action,FPS |