Eu tenho uma matriz de carimbos de data/hora em um bloco de código PLPGSQL: timestamp_array
.
Para cada elemento de timestamp_array
eu quero pegar o próprio elemento ( timestamp_element
) e algumas colunas de uma tabela ( my_table
) que também tem uma coluna timestamp, mas não quero pegar a coluna timestamp em si, mas sim o elemento timestamp array. A condição é que eu só queira obter uma linha da tabela para cada elemento da matriz, a correspondência mais próxima (no passado) entre os elementos de carimbo de data/hora na matriz e a coluna de carimbo de data/hora da tabela.
O que eu quero alcançar é algo como:
FOR EACH timestamp_element IN ARRAY timestamp_array
LOOP
EXECUTE $EXE$
SELECT my_table.some_other_columns...
FROM my_table
WHERE my_table.timestamp <= $1
ORDER BY my_table.timestamp DESC
LIMIT 1
$EXE$
USING timestamp_element
INTO tmp_array;
EXECUTE
INSERT INTO temporary_table
VALUES ($1, array_to_string($2, ', '))
USING timestamp_element, tmp_array;
END LOOP;
Não sei se o código anterior está 100% correto, mas é apenas para tentar explicar melhor o que quero alcançar. E, obviamente, o objetivo seria fazer o trabalho com apenas uma consulta, em vez de uma consulta por elemento de matriz.
Para colocar como um caso prático, se eu tiver um my_table
:
carimbo de data/hora | Cola | ... |
---|---|---|
2020-02-13 23:12:07 | 12 | ... |
27-03-2020 10:37:01 | 15 | ... |
14-06-2020 16:32:44 | 7 | ... |
14-06-2020 17:01:57 | 33 | ... |
Com um timestamp_array
:
[
2020-02-15 12:00:00,
2020-03-22 00:00:00,
2020-06-14 17:00:00
]
Eu gostaria do seguinte temporary_table
sem usar uma consulta independente para cada elemento da matriz:
carimbo de data/hora | Cola | ... |
---|---|---|
2020-02-15 12:00:00 | 12 | ... |
2020-03-22 00:00:00 | 12 | ... |
2020-06-14 17:00:00 | 7 | ... |
unnest()
a matriz e execute umaLATERAL
subconsulta em sua tabela:SQL puro. Você pode aninhá-lo em um bloco PL/pgSQL, é claro.
Mas você certamente não precisa de SQL dinâmico
EXECUTE
para isso.Talvez adicionar outra
ORDER BY
expressão para desempate e obter resultados determinísticos semy_table.timestamp
não forUNIQUE
.Se
my_table
for grande, certifique-se de ter um índice(timestamp)
para torná-lo rápido.LEFT JOIN .. ON true
mantém tudotimestamp_element
no resultado, mesmo que nenhuma linha anterior seja encontrada emmy_table
.Ver: