繁体   English   中英

如何在表达式中重用另一个结果列的结果列

[英]How to reuse a result column in an expression for another result column

例:

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

当然这是无效的(至少在Postgres中)但如何在查询中实现相同而不重写子查询两次?

像这样:

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

您可以像这样重用查询:

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

这里有一点需要注意。 第一种方法更具可读性和可重用性,但第二种方法可能更快,因为数据库可能会为它选择更好的计划。

也许sql“with”子句可以提供帮助,如http://orafaq.com/node/1879所示 (其他数据库如Postgres也可以这样做,而不仅仅是oracle)。

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

实际上我在这方面做了很多工作,并打了很多砖墙,但最终找到了答案 - 更多的是黑客 - 但它工作得很好,并将我的查询的读取开销减少了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

我现在拥有我需要的所有三个相关的“标量”值,但只需执行一次相关的子查询而不是三次。

我认为以下内容可行:

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);

没有在动物身上测试过 - 你会成为第一个! :-)

分享和享受。

使用交叉申请或外部申请。

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
   (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的2x相同的子查询。

您可以使用这样的用户定义变量

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

http://dev.mysql.com/doc/refman/5.7/en/user-variables.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM