повторно использовать вычисляемое поле в том же запросе - PullRequest
0 голосов
/ 29 мая 2019

У меня есть этот запрос.

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

Целью этого запроса является суммирование некоторых сумм (сумма (сумма)) за период времени.Я также установил пол на эту сумму в 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 жалуется, что итоговое значение не является известным полем (оно является производным).Первый запрос работает, но он не эффективен.Чего мне не хватает для работы второго?

Ответы [ 4 ]

2 голосов
/ 29 мая 2019

Вы можете использовать общее табличное выражение (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 голос
/ 29 мая 2019

Псевдонимы столбцов не могут быть повторно использованы в SELECT, где они определены - и по простой причине. 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.
  • Арифметика даты работает как для дат, так и для значений даты / времени.
0 голосов
/ 29 мая 2019

Вы можете исправить это как

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
0 голосов
/ 29 мая 2019

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
...