2017-01-18 6 views
0

У меня есть список людей, и я хочу получить количество людей, сгруппированных по годам, в которых дана собственность в этом году. Проблема в том, что количество лет, которые я хочу найти, это от текущего назад, я хочу, чтобы пользователь его выбрал. В настоящее время я получаю информацию 10 лет назад, но я хочу, чтобы пользователь мог ввести любое количество лет.Как перебирать значения на каждой итерации и возвращать их в список

CREATE OR REPLACE FUNCTION convertidos_neto_10_year_ago(IN aidiglesia integer) 

    RETURNS TABLE(cant0 bigint, cant1 bigint, cant2 bigint, cant3 bigint, cant4 bigint, cant5 bigint, cant6 bigint, cant7 bigint, cant8 bigint, cant9 bigint, cant10 bigint) AS 

$BODY$BEGIN 

RETURN Query SELECT 

(SELECT count(jb_persona.id) 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = date_part('year'::text, ('now'::text)::date) - (10)::double precision))) , 

(SELECT count(jb_persona.id) 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (9)::double precision)))) , 

(SELECT count(jb_persona.id) AS count3 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (8)::double precision)))) , 

(SELECT count(jb_persona.id) AS count4 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (7)::double precision)))) , 

(SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (6)::double precision)))) , 

(SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (5)::double precision)))) , 

(SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (4)::double precision)))) , 

    (SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (3)::double precision)))) , 

(SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (2)::double precision)))) , 

(SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (1)::double precision)))) , 

(SELECT count(jb_persona.id) AS count5 
      FROM jb_persona 
      WHERE ((jb_persona.id_iglesiafk = aidiglesia) AND (date_part('year'::text, jb_persona.fecha_conversion) = (date_part('year'::text, ('now'::text)::date) - (0)::double precision)))); 

END; 

$BODY$ 

    LANGUAGE plpgsql VOLATILE 
    COST 100 
    ROWS 1000; 

ALTER FUNCTION convertidos_neto_10_year_ago(integer) 

OWNER TO postgres; 
+0

так что вы хотите динамическое число столбцов, возвращаемых функцией в зависимости от этого аргумента функции? .. –

+0

Переменное количество столбцов непросто и требует специального синтаксиса вызова (движок PostgreSQL должен знать, сколько столбцов будет возвращено из вызова - и с которым введите точно). - Почему не просто 'WHERE date_part ('year', fecha_conversion) + 10> = date_part ('year', now()) GROUP BY date_part ('year', fecha_conversion)'? (Это приведет к нескольким строкам вместо нескольких столбцов) – pozs

+0

да, @VaoTsun. но может быть одним столбцом и динамическим числом строк. если год составляет 10, то один столбец и 10 строк ... – meyquel

ответ

1

также иметь нулевые счета лет на выходе внешнего соединения сгенерированный год серии:

select to_char(d, 'YYYY') as year, count(id) as total 
from 
    jb_persona 
    right join 
    generate_series(
     date_trunc('year', now() - interval '10 years'), 
     now(), interval '1 year' 
    ) gs(d) on gs.d = date_trunc('year', fecha_conversion) 
where id_iglesiafk = aidiglesia 
group by 1 

Если вы хотите, чтобы в качестве столбцов простое решение это иметь его как JSON:

select jsonb_object_agg(year, total) 
from (
    select to_char(d, 'YYYY') as year, count(id) as total 
    from 
     jb_persona 
     right join 
     generate_series(
      date_trunc('year', now() - interval '10 years'), 
      now(), interval '1 year' 
     ) gs(d) on gs.d = date_trunc('year', fecha_conversion) 
    where id_iglesiafk = aidiglesia 
    group by 1 
) s 

Для 9.4 использования:

select jsonb_object(array_agg(year), array_agg(total::text)) 
from ... 
+0

нетто, спасибо Вам но: [Err] ОШИБКА: нет Existe ла несильно jsonb_object_agg (текст, BIGINT) ЛИНИЯ 1: выберите jsonb_object_agg (лет, всего) ^ ПОДСКАЗКА: Ninguna несильно совпадают ан-эль Nombre у Tipos де argumentos Puede сер necesario agregar конверсия explícita. de tipos. – meyquel

+0

@meyquel Что такое версия Postgresql? –

+0

postgres 9.4 version – meyquel