Выберите таблицу или массив для каждой строки большего запроса на выборку. - PullRequest
3 голосов
/ 22 декабря 2010

Использование 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 - это массив или что-то в этом роде (не связанная строка)?

Ответы [ 3 ]

7 голосов
/ 22 декабря 2010

Вы можете использовать курсоры уровня поля:

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
1 голос
/ 22 декабря 2010

Чтобы построить ответ 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 голосов
/ 22 декабря 2010

ПРИМЕЧАНИЕ : это даст вам строку (не то, что вы хотели), но я оставлю этот ответ здесь, поскольку этот вопрос задают довольно часто, и не все люди еще знают о таком простом решении

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

Если вам нужны круглые скобки вокруг списка идентификаторов сообщений, вы можете использовать конкатенацию:

'(' || wm_concat(message_code) || ')' AS message
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...