2010-12-22 83 views
3

使用Oracle 11g選擇一個表或數組一個更大的選擇查詢

假設中的每一行,我們有兩個表:

CREATE TABLE items (
    item_id NUMBER(22,0) 
); 

CREATE TABLE messages (
    item_id NUMBER(22,0), 
    message_code NUMBER(22,0) 
); 

那裏是一個(項目)很多(消息)的關係。我想在一個查詢中選擇所有的東西,以將其轉換爲java。是否可以寫這樣的查詢,它會給我喜歡輸出:

ID   MESSAGE 
---------------------------------- 
1   (100, 105, 201) 
2   (100, 105) 

而MESSAGE列是一個數組或類似的東西(不是一個連接字符串)?

+0

爲什麼你不想每個ID使用多行?一旦你脫離關係模型就很難回頭了,最終你會支持各種奇怪的查詢,這些查詢在很多情況下都是無用的。 – 2010-12-22 14:24:47

+0

@jonearles:查詢如何破壞模型? – Quassnoi 2010-12-23 11:43:04

回答

1

爲了鞏固Quassnoi的答案,還有的COLLECT功能,會做同樣的事情,MULTISET在其他回答但沒有子查詢。

CREATE TYPE t_message_code AS TABLE OF INTEGER; 

WITH items AS 
     (
     SELECT 1 AS item_id 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id 
     FROM dual 
     ), 
     messages AS 
     (
     SELECT 1 AS item_id, 100 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 1 AS item_id, 105 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 1 AS item_id, 201 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id, 100 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id, 15 AS message_code 
     FROM dual 
     ) 
SELECT i.item_id, 
    cast(collect(m.message_code) as t_message_code) as messages_codes 
FROM  
    items i 
    join messages m on (m.item_id = i.item_id) 
group by i.item_id; 
0

注意:這會給你一個字符串(不是你想要的),但由於這個問題是問經常我會離開這裏,這個答案並沒有所有的人都知道這種簡單的解決方案

SELECT item_id AS id, 
     wm_concat(message_code) AS message 
    FROM messages 
GROUP BY item_id 

如果你需要的信息加上括號IDS列出你可以使用串聯:

'(' || wm_concat(message_code) || ')' AS message 
+0

這將導致連接字符串 – Quassnoi 2010-12-22 13:01:40

7

您可以使用字段級光標:

WITH items AS 
     (
     SELECT 1 AS item_id 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id 
     FROM dual 
     ), 
     messages AS 
     (
     SELECT 1 AS item_id, 100 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 1 AS item_id, 105 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 1 AS item_id, 201 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id, 100 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id, 15 AS message_code 
     FROM dual 
     ) 
SELECT item_id, 
     CURSOR 
     (
     SELECT message_code 
     FROM messages m 
     WHERE m.item_id = i.item_id 
     ) 
FROM items i 

或創建一個表型和投值的MULTISET該類型:

CREATE TYPE t_message_code AS TABLE OF INTEGER 

WITH items AS 
     (
     SELECT 1 AS item_id 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id 
     FROM dual 
     ), 
     messages AS 
     (
     SELECT 1 AS item_id, 100 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 1 AS item_id, 105 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 1 AS item_id, 201 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id, 100 AS message_code 
     FROM dual 
     UNION ALL 
     SELECT 2 AS item_id, 15 AS message_code 
     FROM dual 
     ) 
SELECT item_id, 
     CAST 
     (
     MULTISET 
     (
     SELECT message_code 
     FROM messages m 
     WHERE m.item_id = i.item_id 
     ) AS t_message_code 
     ) 
FROM items i