powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / nested table при группировке пробросить его значение без изменений дальше
10 сообщений из 10, страница 1 из 1
nested table при группировке пробросить его значение без изменений дальше
    #39915405
Фотография Shredder2003
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если группировать по полю с 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
nested table при группировке пробросить его значение без изменений дальше
    #39915429
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
nested table при группировке пробросить его значение без изменений дальше
    #39915479
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shredder2003
Преобразование типа в текст
Можно группировать в json array, если версия позволяет прозрачно кастить обратно в объектный тип, или collect. Возможно эффективнее будет использовать самописный агрегат first_address_tab().
...
Рейтинг: 0 / 0
nested table при группировке пробросить его значение без изменений дальше
    #39915482
Фотография Shredder2003
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
nested table при группировке пробросить его значение без изменений дальше
    #39915495
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shredder2003,

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

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

.....
stax
...
Рейтинг: 0 / 0
nested table при группировке пробросить его значение без изменений дальше
    #39915496
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
nested table при группировке пробросить его значение без изменений дальше
    #39915500
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
nested table при группировке пробросить его значение без изменений дальше
    #39915526
Фотография Shredder2003
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег
можно сделать объектную обёртку над массивом для группировки.


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

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

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

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

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

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


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