Puede utilizar una expresión de tabla común, CTE, para calcular primero los valores de los centroides, por ejemplo
WITH
centroids(geom) AS
(SELECT ST_Centroid(geom)
FROM table1)
SELECT t2.*, t3.*, t4.*
FROM table2 t2, table3 t3, table3 t4, centroids ct
WHERE ST_Contains(t2.geom, ct.geom)
AND ST_Contains(t3.geom, ct.geom)
.....
En el caso de su consulta, en la que ST_Centroid(tabla1.geom) se reutiliza varias veces, es muy probable que el optimizador de consultas de Postgres reescriba la consulta para que ST_Centroid(tabla1.geom) sólo se llame una vez. Puede comprobarlo poniendo EXPLAIN
delante de su consulta y comparando los dos planes. Explicar los planes puede ser bastante difícil de comprender al principio, pero sospecho que la salida será la misma para esta consulta escrita de ambas maneras, lo que significa que mientras en SQL/inglés te preocupa repetirte, la consulta analizada no lo hará.
En general, si necesita referirse a alguna tabla de entrada varias veces en una consulta compleja, pero utilizando un subconjunto diferente de los datos, diferentes columnas, o diferentes llamadas a funciones sobre esos datos, entonces el enfoque CTE es bueno, ya que sólo tiene que obtener de esa tabla una vez.
NOTA . Es muy probable que la consulta anterior falle. No sé cuál es la estructura de tus tablas, y es posible que, si no hay ninguna columna compartida, puedas escribir simplemente SELECT * FROM t1, t2, t3
etc. También es posible, que si estas tablas comparten una estructura similar, entonces se está buscando un UNION SELECT
.