Как получить уникальное значение столбца из объекта таблицы оракула - PullRequest
0 голосов
/ 28 октября 2019

У меня есть объект типа таблицы оракула, и я хочу получить только уникальные значения из определенного столбца без циклической обработки с использованием индекса.

Например, я хотел бы достичь чего-то подобного.

 SELECT SET (NUMBER_TBL.S_NO)
   INTO NumbersTab
   FROM dual;

1 Ответ

4 голосов
/ 28 октября 2019

Вам нужно извлечь столбец из типа объекта, а затем повторно объединить в коллекцию простого типа, а затем вы можете использовать функцию SET():

Oracle Setup :

CREATE TYPE NUMBER_OBJ AS OBJECT( s_no NUMBER )
/
CREATE TYPE NUMBER_TBL AS TABLE OF NUMBER_OBJ
/
CREATE TYPE number_list AS TABLE OF NUMBER
/

CREATE TABLE test_data ( numbers NUMBER_TBL )
NESTED TABLE numbers STORE AS test_data__numbers
/
BEGIN
  INSERT INTO test_data
  VALUES (
    NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    )
  );

  INSERT INTO test_data
  VALUES (
    NUMBER_TBL(
      NUMBER_OBJ( 5 ),
      NUMBER_OBJ( 5 ),
      NUMBER_OBJ( 5 ),
      NUMBER_OBJ( 6 ),
      NUMBER_OBJ( 6 ),
      NUMBER_OBJ( 5 )
    )
  );
END;
/

SQL-запрос :

SELECT SET( CAST( COLLECT( n.s_no ORDER BY n.s_no ) AS number_list ) )
FROM   test_data t
       CROSS JOIN TABLE( t.numbers ) n
GROUP BY t.rowid

Вывод :

| SET(CAST(COLLECT(N.S_NOORDERBYN.S_NO)ASNUMBER_LIST)) |
|------------------------------------------------------|
|                                              1,2,3,4 |
|                                                  5,6 |

SQLFiddle

PL / SQL Option 1 - SET

DECLARE
  n_tbl NUMBER_TBL := NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    );
  NumbersTab number_list;
BEGIN
  SELECT SET(
           CAST(
             COLLECT( s_no ORDER BY s_no )
             AS number_list
           )
         )
  INTO   NumbersTab
  FROM   TABLE( n_tbl );

  FOR i IN 1 .. NumbersTab.COUNT LOOP
    DBMS_OUTPUT.PUT( NumbersTab(i) || ',' );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( '' );
END;
/

PL / SQL Option 2 - SQL не используетсяSET:

DECLARE
  n_tbl NUMBER_TBL := NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    );
  NumbersTab number_list;
BEGIN
  NumbersTab := number_list();
  NumbersTab.EXTEND( n_tbl.COUNT );
  FOR i IN 1 .. n_tbl.COUNT LOOP
    NumbersTab(i) := n_tbl(i).s_no;
  END LOOP;
  NumbersTab := SET( NumbersTab );

  FOR i IN 1 .. NumbersTab.COUNT LOOP
    DBMS_OUTPUT.PUT( NumbersTab(i) || ',' );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( '' );
END;
/

PL / SQL Option 3 - BULK COLLECT INTO:

DECLARE
  n_tbl NUMBER_TBL := NUMBER_TBL(
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 1 ),
      NUMBER_OBJ( 2 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 3 ),
      NUMBER_OBJ( 4 )
    );
  NumbersTab number_list;
BEGIN
  SELECT DISTINCT s_no
  BULK COLLECT INTO NumbersTab
  FROM   TABLE( n_tbl )
  ORDER BY s_no;

  FOR i IN 1 .. NumbersTab.COUNT LOOP
    DBMS_OUTPUT.PUT( NumbersTab(i) || ',' );
  END LOOP;
  DBMS_OUTPUT.PUT_LINE( '' );
END;
/

все выходные данные:

1,2,3,4,

дБ <> скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...