sábado, marzo 29, 2008

split_part in db2

En vista de que no encontre ninguna funcion de db2 8.x.x que hiciera un split en un campo varchar decidi implementar una, lo que hace es dividir un campo varchar separado por algun caracter.


SELECT split_part('pru|ba|prueba','|',2) FROM sysibm.sysdummy1;
1
----
ba


he aqui el codigo:


CREATE FUNCTION split_part ( string varchar(60),caracter varchar(5), position integer )
RETURNS varchar(20)
LANGUAGE SQL
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
RETURN
WITH series2(seq) AS
(
VALUES (1)
UNION ALL
SELECT seq + 1 FROM series2 WHERE seq < length(string)+2
),
series(seq) as ( SELECT DISTINCT seq FROM series2 ORDER BY seq)
SELECT final
FROM ( SELECT substr(string,S1.seq,min(S2.seq) - S1.seq -1) as final,
row_number() over() as row_num
FROM series AS S1, series AS S2
WHERE substr (caracter || string || caracter,S1.seq ,1) = caracter
AND substr (caracter || string || caracter, S2.seq , 1) =caracter
AND S1.seq < S2.seq
GROUP BY string, S1.seq) as temp2
WHERE row_num = position;


En la linea 14 Sequence(seq) as ( select distinct seq from Sequence2 order by seq) se hace por optimización, y la verdad no se si se pudiera meter adentro de la primera tabla recursiva, si no se hace un ordenamiento entonces el join de la linea 21 AND S1.seq < S2.seq seria hecho secuencialmente, lo que alentaria el proceso que de por si ocupa demasiada fuerza bruta.

Claro que con postgres 8.3 las cosas son más faciles

miguel=# explain select split_part(name,'|',2) from test_names ;
QUERY PLAN
-----------------------------------------------------------
Seq Scan on test_names (cost=0.00..1.05 rows=4 width=13)
(1 row)


Lo unico malo es que no tengo un servidor de db2 como para hacer pruebas más certeras y para entenderle más a los datos que arroja su optimizador, cosa que no he podido comprender del todo.

No hay comentarios.: