示例:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
当然这是无效的(至少在Postgres中)但如何在不重写子查询两次的情况下在查询中实现相同的效果?
答案 0 :(得分:42)
像这样:
SELECT
turnover,
cost,
turnover - cost as profit
from (
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as partial_sums
答案 1 :(得分:12)
你可以重复使用这样的查询:
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
这相当于:
SELECT *
FROM(
SELECT
TURNOVER.sum as SUM_TURNOVER
FROM
(
SELECT SUM(...) FROM ...)
)AS TURNOVER,
(
SELECT SUM(...) FROM ...
)AS COST
WHERE ....
) AS a
这里有一点需要注意。第一种方法更具可读性和可重用性,但第二种方法可能更快,因为数据库可能会为它选择更好的计划。
答案 2 :(得分:6)
也许sql“with”子句可以提供帮助,如此处所示http://orafaq.com/node/1879(其他数据库如Postgres也可以这样做,而不仅仅是oracle)。
答案 3 :(得分:4)
SELECT turnover, cost, turnover - cost
FROM
(
SELECT
(SELECT ...) as turnover,
(SELECT ...) as cost
) as Temp
答案 4 :(得分:4)
实际上我在这方面做了很多工作,打了很多砖墙,但终于找到了答案 - 更多的是黑客 - 但它工作得非常好,并将我的查询的读取开销减少了90%......
因此,我不是多次复制相关查询以从子查询中检索多个列,而是使用concat将所有值返回到逗号分隔的varchar中,然后在应用程序中再次将它们展开...
所以而不是
select a,b,
(select x from bigcorrelatedsubquery) as x,
(select y from bigcorrelatedsubquery) as y,
(select z from bigcorrelatedsubquery) as z
from outertable
我现在做
select a,b,
(select convert(varchar,x)+','+convert(varchar,x)+','+convert(varchar,x)+','
from bigcorrelatedsubquery) from bigcorrelatedquery) as xyz
from outertable
group by country
我现在拥有了我需要的所有三个相关的“标量”值,但只需执行一次相关的子查询而不是三次。
答案 5 :(得分:3)
我认为以下内容可行:
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);
未在动物身上进行测试 - 您将成为第一个! : - )
分享并享受。
答案 6 :(得分:0)
使用交叉申请或外部申请。
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
答案 7 :(得分:0)
这已经很老了,但我遇到了这个问题并看到了这篇文章,但没有设法用给定的答案来解决我的问题,所以我最终得出了这个解决方案:
如果您的查询是:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
您可以将其转换为子查询,然后使用以下字段:
SELECT *,(myFields.turnover-myFields.cost) as profit
FROM
(
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as myFields
我不完全确定这是否是一种糟糕的做事方式,但性能明智,我可以查询224,000
记录花了1.5秒
不确定它后来是否变成了DB的相同子查询的2倍。
答案 8 :(得分:-1)
您可以使用此类用户定义的变量
SELECT
@turnover := (SELECT SUM(...) FROM ...),
@cost := (SELECT SUM(...) FROM ...),
@turnover - @cost as profit