Em um banco de dados de transações que abrangem milhares de entidades ao longo de 18 meses, eu gostaria de executar uma consulta para agrupar todos os períodos de 30 dias possíveis entity_id
com uma SOMA de seus valores de transação e COUNT de suas transações nesse período de 30 dias, e retornar os dados de uma maneira que eu possa consultar. Após muitos testes, esse código realiza muito do que eu quero:
SELECT id, trans_ref_no, amount, trans_date, entity_id,
SUM(amount) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_total,
COUNT(id) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_count
FROM transactiondb;
E eu vou usar em uma consulta maior estruturada algo como:
SELECT * FROM (
SELECT id, trans_ref_no, amount, trans_date, entity_id,
SUM(amount) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_total,
COUNT(id) OVER(PARTITION BY entity_id, date_trunc('month',trans_date) ORDER BY entity_id, trans_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS trans_count
FROM transactiondb ) q
WHERE trans_count >= 4
AND trans_total >= 50000;
O caso que esta consulta não cobre é quando a contagem da transação se estende por vários meses, mas ainda fica dentro de 30 dias um do outro. Esse tipo de consulta é possível com o Postgres? Nesse caso, agradeço qualquer contribuição. Muitos dos outros tópicos discutem agregados "em execução ", não rolando .
Atualizar
O CREATE TABLE
script:
CREATE TABLE transactiondb (
id integer NOT NULL,
trans_ref_no character varying(255),
amount numeric(18,2),
trans_date date,
entity_id integer
);
Os dados de amostra podem ser encontrados aqui . Estou executando o PostgreSQL 9.1.16.
A produção ideal incluiria SUM(amount)
e COUNT()
de todas as transações em um período contínuo de 30 dias. Veja esta imagem, por exemplo:
O destaque verde da data indica o que está sendo incluído na minha consulta. O destaque da linha amarela indica os registros que eu gostaria de fazer parte do conjunto.
Leitura anterior:
entity_id
em uma janela de 30 dias a partir de cada transação real. Pode haver várias transações para o mesmo (trans_date, entity_id)
ou essa combinação é definida como única? Sua definição da tabela não tem UNIQUE
ou restrição PK, mas as restrições parecem estar faltando ...
id
chave primária. Pode haver várias transações por entidade por dia.
every possible 30-day period by entity_id
que você quer dizer o período pode começar a qualquer dia, para 365 possíveis períodos em um (não-bissexto) ano? Ou você deseja considerar apenas os dias com uma transação real como início de um período individualmente para algumentity_id
? De qualquer forma, forneça sua definição de tabela, versão do Postgres, alguns dados de amostra e o resultado esperado para a amostra.