PostgreSQL - Resultado de función PostgreSQL

 
Vista:
sin imagen de perfil
Val: 39
Ha aumentado 1 puesto en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por José Vicente (28 intervenciones) el 05/10/2019 14:15:33
Hola, tengo la siguiente función en PostgreSQL:
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
CREATE OR REPLACE FUNCTION public.dias_sin()
 RETURNS int AS $$
 
DECLARE
 
 	diferencia INT;
	contador int;
	provisional int;
	resultado int :=0;
 
BEGIN
     select into contador max (salida_num) from datos;
	 for provisional in 1..contador loop
 
	 SELECT max(DT2.FECHA::DATE - DT1.FECHA::DATE) INTO  diferencia
 
      FROM DATOS DT1, DATOS DT2  WHERE DT1.SALIDA_NUM = DT2.SALIDA_NUM + 1;
 
	  	if resultado < diferencia then resultado := diferencia;
				diferencia :=0;
 
			end if;
 
    	end loop;
 
   return resultado;
end;
 
$$ LANGUAGE plpgsql;
Mi problema es que no recorre del todo la tabla para devolver la máxima diferencia entre dos fechas, se queda con la primera diferencia que encuentra. Ya he probado con for, while y no hay manera, siempre me devuelve el mismo resultado que no es correcto.
¿Qué puedo hacer? Gracias. Un saludo.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Francisco
Val: 256
Oro
Ha mantenido su posición en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por Francisco (110 intervenciones) el 08/10/2019 19:51:21
Hola

Imagino que estas tratando de calcular la diferencia de dias entre fechas, entre un registro y otro

Para esto debe usar windows functions como LAG() OVER(...)

1
2
3
4
5
6
7
SELECT
    t.id,
    t.fecha,
    LAG(t.fecha,1) OVER(PARTITION BY t.id ORDER BY t.fecha) next_date,
    t.fecha - LAG(t.fecha,1) OVER(PARTITION BY t.id ORDER BY t.fecha) diff
FROM (SELECT 1 id, fecha::date fecha FROM datos ORDER BY fecha::date) t
ORDER BY t.id, t.fecha;

Una sola sentencia ejecuta lo que necesitas

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 39
Ha aumentado 1 puesto en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por José Vicente (28 intervenciones) el 09/10/2019 08:10:50
Gracias, pero tengo dos preguntas, en primer lugar ¿Cómo lo aplico en mi función? y segunda cuestión, sólo necesito un resultado, no una tabla, ¿Sería con MAX?. Gracias. Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Francisco
Val: 256
Oro
Ha mantenido su posición en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por Francisco (110 intervenciones) el 10/10/2019 01:46:54
Hola

Si usando MAX() y guardandolo en una variable que retornaras mas adelante

1
2
3
4
5
6
7
8
9
10
11
DECLARE
    days int;
BEGIN
SELECT
    t.id,
    MAX( t.fecha - LAG(t.fecha,1) OVER(PARTITION BY t.id ORDER BY t.fecha) ) diff INTO days
FROM (SELECT 1 id, fecha::date fecha FROM datos ORDER BY fecha::date) t
GROUP by t.id;
 
RETURN days;
END;

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 39
Ha aumentado 1 puesto en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por José Vicente (28 intervenciones) el 10/10/2019 10:24:11
Hola, me da el error:
ERROR: las llamadas a funciones de agregación no pueden contener llamadas a funciones de ventana deslizante
LINE 5: MAX( t.fecha - LAG(t.fecha,1) OVER(PARTITION BY t.id ORD...
^
QUERY: SELECT

t.id,

MAX( t.fecha - LAG(t.fecha,1) OVER(PARTITION BY t.id ORDER BY t.fecha) ) diff FROM (SELECT 1 id, fecha::date fecha FROM datos ORDER BY fecha::date) t

GROUP by t.id
CONTEXT: función PL/pgSQL dias_sin() en la línea 8 en sentencia SQL
Estado SQL: 42803
La función me ha quedado así:
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
CREATE OR REPLACE FUNCTION public.dias_sin()
    RETURNS integer
    LANGUAGE 'plpgsql'
 
    COST 100
    VOLATILE
AS $BODY$
 
DECLARE
 
 	days int;
 
BEGIN
     SELECT
 
    t.id,
 
    MAX( t.fecha - LAG(t.fecha,1) OVER(PARTITION BY t.id ORDER BY t.fecha) ) diff INTO days
 
FROM (SELECT 1 id, fecha::date fecha FROM datos ORDER BY fecha::date) t
 
GROUP by t.id;
 
 
 
RETURN days;
end;
 
$BODY$;
¿Qué falla?. Gracias. Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Francisco
Val: 256
Oro
Ha mantenido su posición en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por Francisco (110 intervenciones) el 10/10/2019 19:35:57
Hola

Ciertamente, reemplazar la sentencia que da problemas con esta

1
2
3
4
5
6
7
8
9
10
11
12
13
WITH dias AS (
	SELECT
	    t.id,
	    t.fecha - LAG(t.fecha,1) OVER(PARTITION BY t.id ORDER BY t.fecha) diff
	FROM (
		SELECT
			1 id,
			fecha::date fecha
		FROM datos
		ORDER BY fecha::date) t
)
SELECT MAX(d.diff) INTO days
FROM dias d;

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 39
Ha aumentado 1 puesto en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

Resultado de función PostgreSQL

Publicado por José Vicente (28 intervenciones) el 11/10/2019 13:57:58
Muchas gracias, ya funciona correctamente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar