加入计算列值无法给出预期结果

join on a calculated column value fails to give the expected result

table 运动

id data data_val descrizione banca movimento importo id_volte saldo_carta utenza created_on
3 2021-03-14 2021-03-14 Rata Mutuo 6 21 560.00 5 NULL 2 2021-03-02 17:57:38
4 2021-04-14 2021-04-14 Rata Mutuo 6 21 560.00 5 NULL 2 2021-03-02 17:57:38
27 2021-03-01 2021-03-27 Stipendio Mensile 6 20 2500.00 6 NULL 2 2021-03-02 17:57:47
28 2021-04-01 2021-04-27 Stipendio Mensile 6 20 2500.00 6 NULL 2 2021-03-02 17:57:47
49 2021-03-02 2021-04-16 prova 6 21 134.00 0 3032021 2 2021-03-02 19:23:02
51 2021-03-05 2021-04-16 prova1 6 21 432.00 0 3032021 2 2021-03-02 19:48:35

table movimenti_periodici

id nome
0 Singolo
5 mutuo
6 stipendio

Table因果关系

id nome
23 Interessi Attivi
24 Interessi Passivi
21 Rata Mutuo
13 Saldo carta di credito
20 Stipendio

查询:

SELECT 
    MAX(data_val) as data, 
    IF(COUNT(*) > 1, 'Saldo Carta', MAX(descrizione)) AS descrizione,
    IF(COUNT(*) > 1, 13, MAX(movimento)) AS movimento,
    MAX(causali.nome),
    SUM(importo) as importo, 
    MAX(movimenti_periodici.nome) as periodico
FROM `movimenti` 
    JOIN causali ON movimenti.movimento=causali.id 
    JOIN movimenti_periodici ON movimenti.id_volte=movimenti_periodici.id 
WHERE movimenti.utenza=2 
    AND data BETWEEN '2021-03-01'  AND '2021-04-30' 
    AND movimenti.banca=6
 group by saldo_carta, data_val
 ORDER BY data_val ASC

预期结果

data descrizione movimento nome importo periodico
2021-03-14 Rata Mutuo 21 Rata Mutuo 560.00 mutuo
2021-03-27 Stipendio Mensile 20 Stipendio 2500.00 stipendio
2021-04-14 Rata Mutuo 21 Rata Mutuo 560.00 mutuo
2021-04-16 Saldo Carta 13 Saldo Carta di credito 566.00 Singolo
2021-04-27 Stipendio Mensile 20 Stipendio 2500.00 stipendio

我的查询工作正常并将 table movimenti 的行 4951 聚合在一起(查看 2021-04-16 行的预期结果和实际结果) .对于此聚合移动,movimento 已正确设置为 13,但我无法在与 causali 的连接中使用 13 来显示 nome 匹配 13。它当前从已聚合的行中返回 MAX(nome)。实际结果如下所示:

实际结果

data descrizione movimento nome importo periodico
2021-03-14 Rata Mutuo 21 Rata Mutuo 560.00 mutuo
2021-03-27 Stipendio Mensile 20 Stipendio 2500.00 stipendio
2021-04-14 Rata Mutuo 21 Rata Mutuo 560.00 mutuo
2021-04-16 Saldo Carta 13 Rata Mutuo 566.00 Singolo
2021-04-27 Stipendio Mensile 20 Stipendio 2500.00 stipendio

如何获得预期结果?

我认为最简单的方法是替换:

MAX(causali.nome)

与:

IF(COUNT(*) > 1, (SELECT nome FROM causali WHERE id = 13), MAX(causali.nome))

因为正如我在您的代码中看到的那样,13 是一个硬编码值。

参见 demo(我还为所有表格使用了别名以缩短代码并使其更具可读性)。

您需要计算 ON 条件才能加入 causali table,以获取 moviemento 项目的 nome

处理这个问题的一个好方法是从创建您需要的摘要的子查询开始。

  SELECT data_val,
         IF(COUNT(*) > 1, 'Saldo Carta', MAX(descrizione)) AS descrizione,
         IF(COUNT(*) > 1, 13, MAX(movimento)) AS movimento,
         SUM(importo) AS importo,
         MAX(id_volte) id_volte
    FROM `movimenti` 
   WHERE movimenti.utenza=2 
     AND data BETWEEN '2021-03-01'  AND '2021-04-30' 
     AND movimenti.banca=6
   GROUP BY data_val

然后使用外部查询查找与 id_voltemovimento 关联的名称。

SELECT data_val, 
       descrizione,
       movimento,
       causali.nome,
       importo,
       movimenti_periodici.nome periodico
  FROM ( /* that subquery */ ) summary                             
  JOIN causali ON summary.movimento = causali.id 
  JOIN movimenti_periodici ON summary.id_volte=movimenti_periodici.id 
 ORDER BY data_val  

通过这种方式,您可以将总结交易的工作与使用名称对其进行注释的工作分开,并摆脱大部分 MAX(nome) 的事情。

此处:https://www.db-fiddle.com/f/64JkvyM2bxQ4wRJorJq8t4/3