在同一查询中重用计算字段

时间:2019-05-29 09:31:09

标签: mysql sql calculated-field

我有这个查询。

SELECT carte.nome, sum(amount) AS total, (1500-sum(amount)) AS residuo 
FROM movimenti_carta JOIN carte ON movimenti_carta.banca=carte.id 
WHERE data BETWEEN '2019-05-01' AND '2019-05-31' 
GROUP by banca

此查询的目标是在一段时间内总计一些金额(sum(amount))。我也将下限设置为1500,因此我想在第三个字段中进行数学运算。我试图做

SELECT carte.nome, sum(amount) AS total, (1500-total) AS residuo 
FROM movimenti_carta JOIN carte ON movimenti_carta.banca=carte.id 
WHERE data BETWEEN '2019-05-01' AND '2019-05-31' 
GROUP by banca

但是mysql抱怨totale不是一个已知字段(它是派生的)。 第一个查询有效,但是效率不高。我缺少第二个上班的东西吗?

4 个答案:

答案 0 :(得分:2)

您可以使用通用表表达式(CTE):

WITH cte_query AS (
SELECT carte.nome AS nome, sum(amount) AS total
FROM movimenti_carta JOIN carte ON movimenti_carta.banca=carte.id 
WHERE data BETWEEN '2019-05-01' AND '2019-05-31' 
GROUP by banca
)

SELECT nome, total, (1500- total) AS residuo 
FROM cte_query

子查询也将起作用:

SELECT nome, total, (1500- total) AS residuo 
FROM (
SELECT carte.nome AS nome, sum(amount) AS total
FROM movimenti_carta JOIN carte ON movimenti_carta.banca=carte.id 
WHERE data BETWEEN '2019-05-01' AND '2019-05-31' 
GROUP by banca
) A

答案 1 :(得分:1)

列别名不能在定义它们的SELECT中重复使用-原因很简单。通常,MySQL(尤其是MySQL)和SQL不能保证SELECT中表达式的求值顺序。

对于您而言,最简单的解决方案是重复该表达式,因为它是如此简单。

不过,查询中还有另一个问题。您正在按banca进行汇总,但只能选择nome

这是编写查询的更好方法:

SELECT c.nome, sum(?.amount) AS total,
       (1500 - sum(?.amount)) AS residuo 
FROM movimenti_carta mc JOIN
     carte c
     ON mc.banca = c.id 
WHERE ?.data >= '2019-05-01' AND
      ?.data < '2019-06-01' 
GROUP by c.nome;

请注意更改:

  • 所有列引用均应合格。 ?用于表示该列来自的表的别名。
  • 使用表别名,这是表名称的缩写。
  • SELECT中未聚合的列位于GROUP BY中。
  • 日期算术适用于日期和日期/时间值。

答案 2 :(得分:0)

除非它位于HAVING语句内,否则MySQL不支持使用变量,因此,为了使它起作用,您应该将其重写为

SELECT carte.nome, sum(amount) AS total, (1500-sum(amount)) AS residuo 
FROM movimenti_carta JOIN carte ON movimenti_carta.banca=carte.id 
WHERE data BETWEEN '2019-05-01' AND '2019-05-31' 
GROUP by banca

答案 3 :(得分:0)

您可以将其纠正为

SELECT 
nome ,
total,
 residuo AS residuo_TMP,
 (1500-total) AS residuo 
 FROM 
 (SELECT 
carte.nome,
SUM(amount) AS total,
(1500- SUM(amount)) AS residuo 
 FROM
movimenti_carta 
JOIN carte 
  ON movimenti_carta.banca = carte.id 
 WHERE DATA BETWEEN '2019-05-01' 
AND '2019-05-31' 
GROUP BY banca ) aa