Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / nested table при группировке пробросить его значение без изменений дальше / 10 сообщений из 10, страница 1 из 1
17.01.2020, 13:07
    #39915405
Shredder2003
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
если группировать по полю с nested table, получаем
oracleORA-00932: inconsistent datatypes: expected - got CUSTOM_NESTED_TABLE_TYPE


Известно, что в этой группировке у всех строк в группе одно значение этого поля, т.е. реально не нужно сравнивать значение этого поля из группы - достаточно взять значение этого поля из любой строки группы.
Как это сделать?

Пример:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE TYPE xx_test_address_t AS OBJECT (
   street  VARCHAR2(30),
   city    VARCHAR2(20),
   state   CHAR(2),
   zip     CHAR(5) );
/

CREATE TYPE xx_test_address_tab IS TABLE OF xx_test_address_t;
/

CREATE TABLE xx_test_customers (
   custid  NUMBER,
   name varchar2(200),
   address xx_test_address_tab )
NESTED TABLE address STORE AS xx_test_customer_addresses;

INSERT INTO xx_test_customers VALUES (1, 'ЧОП "Всем по васильку"',
            xx_test_address_tab(
              xx_test_address_t('101 First', 'Redwood Shores', 'CA', '94065'),
              xx_test_address_t('123 Maple', 'Mill Valley',    'CA', '90952')
            )                );
;

select name, max(address)
from xx_test_customers
group by name
;



хотелось бы вместо max что-то, что выдаст любой address из группы, с тем же типом xx_test_address_tab.
Можно взять например max(custid), всунуть это как подселект, а уровнем выше по ИД вытащить значение поля, типа того:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select name
      ,(
        select address
        from xx_test_customers
        where custid = t.max_custid
       ) address
from (
    select name, max(custid) max_custid
    from xx_test_customers
    group by name
) t
;



, но хотелось бы избежать двойного чтения таблицы.
Преобразование типа в текст, группировка текста, затем обратное преобразование в тип нежелательно, т.к. есть вероятность превысить лимит varchar2 в 32К.
...
Рейтинг: 0 / 0
17.01.2020, 13:47
    #39915429
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Shredder2003,

не совсем понял что надо
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SQL> ed
Wrote file afiedt.buf

  1  select
  2  custid
  3  ,max(name) name
  4  ,max(a.street) m_street /* keep */
  5  from xx_test_customers t,table(address) a
  6* group by custid
SQL> /

    CUSTID NAME                           M_STREET
---------- ------------------------------ --------------------
         1 ЧОП "Всем по васильку"         123 Maple



.....
stax
...
Рейтинг: 0 / 0
17.01.2020, 14:42
    #39915479
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Shredder2003
Преобразование типа в текст
Можно группировать в json array, если версия позволяет прозрачно кастить обратно в объектный тип, или collect. Возможно эффективнее будет использовать самописный агрегат first_address_tab().
...
Рейтинг: 0 / 0
17.01.2020, 14:46
    #39915482
Shredder2003
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Stax, что надо, в этом примере:
выборка из таблицы xx_test_customers, сгруппированная по полю name, каждая строка выборки содержит два поля:
1. name
2. address, где address - значение из любой строки этой группы.

Вот решение:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select name
      ,(
        select address
        from xx_test_customers
        where custid = t.max_custid
       ) address
from (
    select name, max(custid) max_custid
    from xx_test_customers
    group by name
) t
;



но оно плохо тем, что тут два чтения одной таблицы.
...
Рейтинг: 0 / 0
17.01.2020, 15:14
    #39915495
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Shredder2003,

у меня мало опыта работы с обьектными таблицами
наскоко я помню для сортировки/группировки обьектный тип должен иметь метод MAP/ORDER

ps
если таблица индексирована по custid,
то имхо не так и страшен "второй" проход

.....
stax
...
Рейтинг: 0 / 0
17.01.2020, 15:15
    #39915496
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
...
Рейтинг: 0 / 0
17.01.2020, 15:28
    #39915500
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Shredder2003
address - значение из любой строки этой группы
Чем не устраивает аналитика?
Код: plsql
1.
2.
3.
4.
5.
6.
select name, address
  from (select name,
               address,
               row_number() over (partition by name order by null) rn
          from xx_test_customers)
 where rn = 1


Можно группировка с заходом по rowid.
Код: plsql
1.
2.
3.
select t.*
  from (select name, min(rowid) row_id from xx_test_customers group by name)
       join xx_test_customers t on row_id = t.rowid



Вообще это всё выглядит как крайне сомнительный дизайн, но если хочется усугубить проблему - можно сделать объектную обёртку над массивом для группировки.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create or replace type ot as object ( 
  a xx_test_address_tab,
  map member function fufu return int)
/
sho err
create or replace type body ot as 
  map member function fufu return int is
  begin
    -- all equal
    return 1;
  end fufu;
end;
/
sho err


Код: plsql
1.
2.
3.
4.
select *
  from (select name, treat(max(ot(address)) as ot).a address
          from xx_test_customers
         group by name)
...
Рейтинг: 0 / 0
17.01.2020, 16:11
    #39915526
Shredder2003
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Кобанчег
можно сделать объектную обёртку над массивом для группировки.


похоже то, что нужно, но уже сделал свою агрегирующую функцию под этот тип.
...
Рейтинг: 0 / 0
17.01.2020, 16:43
    #39915542
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Кобанчег,

про MAP знал, но почему-то засело в голове что надо менять xx_test_address_tab

в сторону "обьектной" обертки не смекнул

....
stax
...
Рейтинг: 0 / 0
17.01.2020, 18:40
    #39915628
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
nested table при группировке пробросить его значение без изменений дальше
Shredder2003
Кобанчег
можно сделать объектную обёртку над массивом для группировки.

похоже то, что нужно, но уже сделал свою агрегирующую функцию под этот тип.

Мне представляется, что в указанных условиях UDAF может быть реализована эффективнее MAP, потому и предложил именно её.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / nested table при группировке пробросить его значение без изменений дальше / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]