varios valores una sumar registros por grupos elementos contar columna campos agrupar agrupados agrupaciones agrupacion sql postgresql subquery

sql - valores - Cómo reutilizar una columna de resultados en una expresión para otra columna de resultados



sumar por grupos en sql (9)

Al igual que:

SELECT turnover, cost, turnover - cost as profit from ( (SELECT SUM(...) FROM ...) as turnover, (SELECT SUM(...) FROM ...) as cost ) as partial_sums

Ejemplo:

SELECT (SELECT SUM(...) FROM ...) as turnover, (SELECT SUM(...) FROM ...) as cost, turnover - cost as profit

Claro que esto no es válido (al menos en Postgres) pero, ¿cómo lograr lo mismo en una consulta sin volver a escribir la subconsulta dos veces?


Creo que lo siguiente funcionará:

SELECT turnover, cost, turnover-cost as profit FROM (SELECT 1 AS FAKE_KEY, SUM(a_field) AS TURNOVER FROM some_table) a INNER JOIN (SELECT 1 AS FAKE_KEY, SUM(a_nother_field) AS COST FROM some_other_table) b USING (FAKE_KEY);

No probado en animales - ¡serás el primero! :-)

Comparte y Disfruta.


De hecho, trabajé mucho en esto y golpeé muchas paredes de ladrillo, pero finalmente descubrí una respuesta, más de un hack, pero funcionó muy bien y redujo la sobrecarga de lectura de mis consultas en un 90% ...

Así que, en lugar de duplicar la consulta correlacionada muchas veces para recuperar varias columnas de la subconsulta, solo usé concat todos los valores que quiero devolver en una varchar separada por comas, y luego los desenrollo nuevamente en la aplicación ...

Así que en lugar de

select a,b, (select x from bigcorrelatedsubquery) as x, (select y from bigcorrelatedsubquery) as y, (select z from bigcorrelatedsubquery) as z from outertable

Ahora hago

select a,b, (select convert(varchar,x)+'',''+convert(varchar,x)+'',''+convert(varchar,x)+'','' from bigcorrelatedsubquery) from bigcorrelatedquery) as xyz from outertable group by country

Ahora tengo los tres valores ''escalares'' correlacionados que necesitaba, pero solo tuve que ejecutar la subconsulta correlacionada una vez en lugar de tres veces.


Esto es bastante antiguo, pero me encontré con este problema y vi esta publicación, pero no pude resolver mi problema con las respuestas dadas, por lo que finalmente llegué a esta solución:

si su consulta es:

SELECT (SELECT SUM(...) FROM ...) as turnover, (SELECT SUM(...) FROM ...) as cost, turnover - cost as profit

puede convertirlo en una subconsulta y luego usar los campos como:

SELECT *,(myFields.turnover-myFields.cost) as profit FROM ( SELECT (SELECT SUM(...) FROM ...) as turnover, (SELECT SUM(...) FROM ...) as cost ) as myFields

No estoy completamente seguro de si esta es una mala forma de hacer las cosas, pero en cuanto al rendimiento, me parece bien que consultar más de 224,000 registros tardó 1.5 segundos en no saber si luego se convirtió en 2x de la misma consulta secundaria por DB.


Podrías reutilizar la consulta así:

WITH TURNOVER AS ( SELECT SUM(...) FROM ...) ), COST AS( SELECT SUM(...) FROM ... ) SELECT * FROM( SELECT TURNOVER.sum as SUM_TURNOVER FROM TURNOVER,COST WHERE .... ) AS a

Esto es equivalente a:

SELECT * FROM( SELECT TURNOVER.sum as SUM_TURNOVER FROM ( SELECT SUM(...) FROM ...) )AS TURNOVER, ( SELECT SUM(...) FROM ... )AS COST WHERE .... ) AS a

Hay un punto a tener en cuenta aquí. El primer método es más legible y reutilizable, pero el segundo método puede ser más rápido, porque la base de datos podría elegir un mejor plan para ello.



Tal vez la cláusula "con" sql podría ayudar, como se presenta aquí http://orafaq.com/node/1879 (otras bases de datos como Postgres también lo hacen, no solo oracle).


Utilice una aplicación de cruz o exterior.

SELECT Calc1.turnover, Calc2.cost, Calc3.profit from cross apply ((SELECT SUM(...) as turnover FROM ...)) as Calc1 cross apply ((SELECT SUM(...) as cost FROM ...)) as Calc2 /* Note there is no from Clause in Calc 3 below. This is how you can "stack" formulas like in excel. You can return any number of columns, not just one. */ cross apply (select Calc1.turnover - Calc2.cost as profit) as Calc3


SELECT turnover, cost, turnover - cost FROM ( SELECT (SELECT ...) as turnover, (SELECT ...) as cost ) as Temp