【问题标题】:join on a calculated column value fails to give the expected result加入计算的列值无法给出预期的结果
【发布时间】:2021-03-03 16:34:41
【问题描述】:

桌运动

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

表格运动周期

id nome
0 Singolo
5 mutuo
6 stipendio

因果关系表

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

我的查询工作正常,并将表movimenti 的行4951 聚合在一起(请参阅2021-04-16 行的预期结果和实际结果)。对于这个聚合运动,movimento 正确设置为13,但我不能在与causali 的连接中使用13 来显示匹配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

我怎样才能得到我的预期结果?

【问题讨论】:

  • 请将 DDL 和初始化作为代码而不是网格。 PS 解释为什么当你得到意想不到的结果时你会期待你所期望的,通过参考权威文档来证明是合理的。这是一个常见问题解答。在考虑发布之前,请阅读手册和谷歌任何错误消息以及您的问题/问题/目标的许多清晰、简洁和精确的措辞,带有和不带有您的特定名称/字符串/数字、“site:stackoverflow.com”和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。 How to Ask

标签: mysql group-by inner-join


【解决方案1】:

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

MAX(causali.nome)

与:

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

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

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

【讨论】:

  • 这是一个很棒的方法。谢谢你的建议。对于别名,我更喜欢使用简单的名称,因为我发现它更好读(但这只是恕我直言)
  • @LelioFaieta 对别名很好,但至少您应该使用表名限定所有列(即使没有任何重复的列名)。这是一种很好的做法,可以帮助您避免难以发现的问题。
  • 是的,你是对的。这是我需要开始做的事情
【解决方案2】:

您需要一个计算的 ON 条件来加入您的 causali 表,以获取 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 2022-12-13
    • 2019-08-18
    • 1970-01-01
    相关资源
    最近更新 更多