在同一查询中重用计算字段
reuse a calculated field in the same query
我有这个问题。
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 不是已知字段(它是派生字段)。
第一个查询有效,但效率不高。我缺少什么才能让第二个工作?
Mysql 不支持使用变量,除非它在 HAVING 语句中,因此要使其工作,您应该将其重写为
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
您可以使用通用 Table 表达式 (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
你可以改正为
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
列别名不能在定义它们的 SELECT
中 re-used -- 原因很简单。 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;
注意变化:
- 所有列引用都应该是合格的。
?
是列来源的 table 的别名。
- 使用 table 别名,它们是 table 名称的缩写。
SELECT
中的未聚合列在 GROUP BY
中。
- 日期算法适用于日期和 date/time 值。
我有这个问题。
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 不是已知字段(它是派生字段)。 第一个查询有效,但效率不高。我缺少什么才能让第二个工作?
Mysql 不支持使用变量,除非它在 HAVING 语句中,因此要使其工作,您应该将其重写为
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
您可以使用通用 Table 表达式 (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
你可以改正为
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
列别名不能在定义它们的 SELECT
中 re-used -- 原因很简单。 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;
注意变化:
- 所有列引用都应该是合格的。
?
是列来源的 table 的别名。 - 使用 table 别名,它们是 table 名称的缩写。
SELECT
中的未聚合列在GROUP BY
中。- 日期算法适用于日期和 date/time 值。