Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Собрать из столбца строку / 20 сообщений из 20, страница 1 из 1
29.01.2013, 09:27
    #38128246
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Здравствуйте, коллеги - есть простенький вопрос!
Пусть дана таблица структуры Create table test_t (ID integer, NAME varchar(50))
Пусть загоняем данные: insert into test_t (ID, NAME) values (1, ',брат') ; insert into test_t (ID, NAME) values (2, ',сестра') ;
Нужно получить строку = 'брат,сестра'. Есть ли какая-нибудь функция которая это автоматом сможет сделать.
Посмотрел RPAD; CONCAT. Или же писать курсор, который будет конкатенировать значения столбцов в одну строку.
Версия СУБД (9.7)
Спасибо!
...
Рейтинг: 0 / 0
29.01.2013, 09:53
    #38128289
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
medoed,

Здравствуйте.

Код: plaintext
1.
2.
3.
4.
select  listagg (name, ',')
from table(values 
  (1, 'брат')
, (2, 'сестра')
) t (id, name)
...
Рейтинг: 0 / 0
29.01.2013, 10:09
    #38128313
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Mark Barinstein,

Спасибо, Марк - вкуриваю!
...
Рейтинг: 0 / 0
29.01.2013, 10:14
    #38128322
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Правильно я понимаю, что данная функция может максимум строку из 4000 за раз символов возвращать?
А если мне надо например 100 000 символов сконкатенировать?
...
Рейтинг: 0 / 0
29.01.2013, 10:31
    #38128365
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
medoedПравильно я понимаю, что данная функция может максимум строку из 4000 за раз символов возвращать?
Нет, максимум - 32K.
Там же написано:

Код: plaintext
1.
The result data type of LISTAGG is based on the data type of string-expression:
If the data type of string-expression is CHAR(n) or VARCHAR(n), the data type of result is VARCHAR( MAX(4000, n))

If the data type of string-expression is GRAPHIC(n or VARGRAPHIC(n), the data type of result is VARGRAPHIC( MAX(2000, n))

The result data type can exceed VARCHAR(4000) or VARGRAPHIC(2000)
if a derived size is used to determine the size of the result, to a maximum of 32 KB if WITHIN GROUP is specified.
The following example successfully yields a return data type of VARCHAR(10000):

LISTAGG(CAST(NAME AS VARCHAR(10000)), ',')
medoedА если мне надо например 100 000 символов сконкатенировать?
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT substr(xmlserialize(
xmlquery('$L/text()' passing XMLAGG(XMLELEMENT(NAME "a", ','||name)) as "L")
as clob(100k)), 2)
FROM table(values 
  (1, 'брат')
, (2, 'сестра')
) t (id, name)
...
Рейтинг: 0 / 0
29.01.2013, 10:33
    #38128371
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Да спасибо, уже нашёл грустно!
Было бы как в MSSQL , было бы ограничение в Varchar (max) , там 2 ГБ
...
Рейтинг: 0 / 0
29.01.2013, 10:35
    #38128373
Собрать из столбца строку
medoedПравильно я понимаю, что данная функция может максимум строку из 4000 за раз символов возвращать?
А если мне надо например 100 000 символов сконкатенировать?
4000 - это не ограничение функции, это ограничение типа данных VARCHAR. А елс инадо больше, то писать самодельную функцию и собирать результат в CLOB
...
Рейтинг: 0 / 0
29.01.2013, 10:52
    #38128400
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
>>Добрый Э - Эх,

Дык это понятно, но в MSSQL 2005 и выше - ограничение на varchar (Varchar(max) )- 2 ГБ.
И не нужен стал CLOB - там где можно обойтись varchar.

Марк - вы не можете VARCHAR(MAX) заказать у разработчиков DB2

Марку отдельное спасибо!
...
Рейтинг: 0 / 0
29.01.2013, 11:34
    #38128473
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
medoedМарк - вы не можете VARCHAR(MAX) заказать у разработчиков DB2
Насколько я знаю, в MSSQL varchar(n) и varchar(max) - разные типы данных.
Считайте, что в DB2 тип данных:
Код: plaintext
CLOB(2G) INLINE LENGTH 312 == VARCHAR(MAX)
в MSSQL.
...
Рейтинг: 0 / 0
29.01.2013, 12:18
    #38128545
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Mark BarinsteinmedoedМарк - вы не можете VARCHAR(MAX) заказать у разработчиков DB2
Насколько я знаю, в MSSQL varchar(n) и varchar(max) - разные типы данных.
Считайте, что в DB2 тип данных:
Код: plaintext
CLOB(2G) INLINE LENGTH 312 == VARCHAR(MAX)
в MSSQL.

MSSQL будет работать такой скрипт:
declare @str_temp varchar(200) = 'Привет медвед!'
declare @str_all varchar(max) = ''
set @str_all = @str_all + @str_temp
print @str_all

Тоесть можно складывать эти разные как вы говорите типы без конвертации + я могу varchar(max) передавать в любую функцию и процедуру, как вариант , предварительно закатав в них XML для парсинга например.

Не уверен , что всё это умеет DB2.
...
Рейтинг: 0 / 0
29.01.2013, 13:08
    #38128638
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
MSSQLMSSQL будет работать такой скрипт:
declare @str_temp varchar(200) = 'Привет медвед!'
declare @str_all varchar(max) = ''
set @str_all = @str_all + @str_temp
print @str_all

Тоесть можно складывать эти разные как вы говорите типы без конвертации + я могу varchar(max) передавать в любую функцию и процедуру, как вариант , предварительно закатав в них XML для парсинга например.

Не уверен , что всё это умеет DB2.

Разные типы - это не значит, что их нельзя использовать вместе.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
set serveroutput on!

begin
  declare @str_temp varchar(200) default 'Привет медвед!';
  declare @str_all clob(2g) default '';
  set @str_all = @str_all || @str_temp;
  call dbms_output.put_line(@str_all);
end!


Неужели сложно проверить?
То же самое с передачей в функции.
...
Рейтинг: 0 / 0
29.01.2013, 13:38
    #38128742
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Mark Barinstein+
MSSQLMSSQL будет работать такой скрипт:
declare @str_temp varchar(200) = 'Привет медвед!'
declare @str_all varchar(max) = ''
set @str_all = @str_all + @str_temp
print @str_all

Тоесть можно складывать эти разные как вы говорите типы без конвертации + я могу varchar(max) передавать в любую функцию и процедуру, как вариант , предварительно закатав в них XML для парсинга например.

Не уверен , что всё это умеет DB2.

Разные типы - это не значит, что их нельзя использовать вместе.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
set serveroutput on!

begin
  declare @str_temp varchar(200) default 'Привет медвед!';
  declare @str_all clob(2g) default '';
  set @str_all = @str_all || @str_temp;
  call dbms_output.put_line(@str_all);
end!


Неужели сложно проверить?
То же самое с передачей в функции.

Да наверное можно тему закрывать - у меня не запускается ваш скрипт, наверное не все опции на серваке подключены.
Я говорил другое, Вы просто меня не захотели услышать!
Если бы функция listagg реализовывалась на MSSQL, то не было бы ограничения в 32 КБ , а было бы ограничение в varchar(max) ибо это для MSSQL родственные типы.
Вообщем то и всё!
...
Рейтинг: 0 / 0
29.01.2013, 18:20
    #38129440
CawaSPb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
medoed,

Если бы у бабушки...
Утверждение эквивалентно тому, что если бы функция LISTAGG(...) реализовывалась в MS SQL, то тип результата был бы
Код: plaintext
VARCHAR(MAX)
(без соответствующих ограничений).

Может да, а может нет.

Мне кажется желание DB2 разработчиков оставить тип результата в пространстве типов VARCHAR() вполне естественно. VARCHAR'ы обрабатываются по-другому. Совсем не так как CLOB (они, как и другие common типы, влезают в страницу памяти/табличного пространства и работа с ними идёт в буффер-пулах).
Многие операции как с самими объектами типа VARCHAR так и с таблицами, их содержащими, идут значительно быстрее, чем с СLOB (или deprecated LONG VARCHAR) объектами.

То же самое то касается и MS SQL:
http://rusanu.com/2010/03/22/performance-comparison-of-varcharmax-vs-varcharn/] http://rusanu.com/2010/03/22/performance-comparison-of-varcharmax-vs-varcharn/
http://richardlees.blogspot.ru/2010/07/varcharmax-performance-in-sql-server.html] http://richardlees.blogspot.ru/2010/07/varcharmax-performance-in-sql-server.html
http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/4de94284-cfe2-4a47-9863-8a2bbce4fb07/] http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/4de94284-cfe2-4a47-9863-8a2bbce4fb07/
Только там "обыкновенный" varchar - 8000, а не 32K

Ну и по крайней мере Вам представили два варианта хоть с VARCHAR результатом, хоть с CLOB. Используйте, что надо.
...
Рейтинг: 0 / 0
29.01.2013, 18:28
    #38129460
CawaSPb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
PS С LOB'ами по возможности нужно работать вообще только LOB LOCATOR'ами.
...
Рейтинг: 0 / 0
29.01.2013, 21:45
    #38129712
medoed
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
>>CawaSPb,
1. Я не говорил, что Varchar(max) - это тип данных который стоит использовать везде и всюду.
То что он медленный и много памяти жрёт - это однозначно! Его надо использовать, только тогда - когда деваться некуда.
Насколько я помню - на такие поля даже индексы не накатываются! Но для гипер больших данных без них не удобно.
2. То что есть функция listagg - это классно , насколько я помню в MSSQL это делается через XML. Я лишь говорил, что если бы функция работала с varchar(MAX), ну вот приспичило 100 000 идентификатор через запятую запихнуть в переменную - было бы классно. Причем varchar (max) - просто удобен для понимания. То что это невозможно для больших объемов в DB2 и надо использовать тот же XML запрос для CLOB в данной функции - тоже понятно.

P.S. Меня недавно в DB2 порадовала тем, что счетчик можно и через identity делать, как в MSSQL , так и через sequence, как в Oracle.
Вот за это разработчикам DB2 уважуха.
...
Рейтинг: 0 / 0
20.03.2013, 17:35
    #38191843
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Mark Barinsteinmedoed,

Здравствуйте.

Код: plaintext
1.
2.
3.
4.
select  listagg (name, ',')
from table(values 
  (1, 'брат')
, (2, 'сестра')
) t (id, name)
Здравствуйте, Mark Barinstein! А для версии 8.2 не подскажете решение? LISTAGG, к сожалению
Код: plaintext
SQL0440N  Не найдено авторизованной подпрограммы "LISTAGG" типа "FUNCTION" с совместимыми аргументами.  SQLSTATE=42884
...
Рейтинг: 0 / 0
20.03.2013, 17:56
    #38191889
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Semen PopovЗдравствуйте, Mark Barinstein! А для версии 8.2 не подскажете решение? LISTAGG, к сожалению
Код: plaintext
SQL0440N  Не найдено авторизованной подпрограммы "LISTAGG" типа "FUNCTION" с совместимыми аргументами.  SQLSTATE=42884
Здравствуйте.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with a (name) as (values 
  ('брат')
, ('сестра')
)
, b (id, name) as (
select rownumber() over(), name
from a
)
, t (id, str) as (
select id, cast(name as varchar(4000))
from b
where id=1
  union all
select b.id, t.str||','||b.name
from b, t
where b.id=t.id+1
)
select str
from t
where id=(select max(id) from b)
...
Рейтинг: 0 / 0
21.03.2013, 08:47
    #38192539
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Mark BarinsteinЗдравствуйте.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with a (name) as (values 
  ('брат')
, ('сестра')
)
, b (id, name) as (
select rownumber() over(), name
from a
)
, t (id, str) as (
select id, cast(name as varchar(4000))
from b
where id=1
  union all
select b.id, t.str||','||b.name
from b, t
where b.id=t.id+1
)
select str
from t
where id=(select max(id) from b)


Mark Barinstein, большое спасибо. Мда-а-а... Что-то так наворочено. Не сочтите за наглость, а не могли бы дать скрипт в отношении таблицы TAB1 (TAB1_ID, FRN_ID, NAM) с группировкой по FRN_ID?
...
Рейтинг: 0 / 0
21.03.2013, 12:00
    #38192847
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Semen Popov,
как-то так
Код: sql
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.
28.
29.
30.
31.
32.
33.
34.
35.
declare global temporary table session.TAB1 (
  TAB1_ID int not null generated always as identity
, FRN_ID int not null
, NAM varchar(20)
) with replace on commit preserve rows;

insert into session.TAB1 (frn_id, nam) values 
  (1,  'n1_1')
, (1,  'n1_2')
, (10, 'n10_1')
, (20, 'n20_1')
, (20, 'n20_2')
, (20, 'n20_3');

with b (frn_id, id, nam) as (
select frn_id, rownumber() over(partition by frn_id order by tab1_id) id, nam
from session.tab1
)
, t (frn_id, id, str) as (
select frn_id, id, cast(nam as varchar(4000))
from b
where id=1
  union all
select b.frn_id, b.id, t.str||','||b.nam
from b, t
where b.frn_id=t.frn_id and b.id=t.id+1
)
select t.frn_id, t.str
from t
join (
select frn_id, max(id) id
from b
group by frn_id
) g on g.frn_id=t.frn_id and g.id=t.id
order by g.frn_id;

...
Рейтинг: 0 / 0
21.03.2013, 15:13
    #38193384
Semen Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Собрать из столбца строку
Mark Barinstein, спасибо
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Собрать из столбца строку / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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