【问题标题】:SQL query (MAX-MIN) is showing wrong resultsSQL 查询 (MAX-MIN) 显示错误的结果
【发布时间】:2018-04-23 09:18:10
【问题描述】:

我正在尝试从我的数据库中计算数据,但首先我注意到我得到的结果中有奇怪的行为,其次,我在提出考虑到重新填充的请求时遇到了问题。

我有一张桌子: 名称 - 日期时间 - 内容

我想按天对行进行分组并选择数字的差异来进行消费。 例如:

Name - DateTime - Content
Foo - 22-04-2018 6:00 - 120
Foo - 22-04-2018 10:00 - 119
Foo - 22-04-2018 16:00 - 118

内容减少了,结果应该是-2。 我的请求的输出 = -2

另一个例子:

Name - DateTime - Content
Foo - 23-04-2018 6:00 - 50
Foo - 23-04-2018 10:00 - 90
Foo - 23-04-2018 16:00 - 120

在这里我们可以注意到这个数字有所增加。这意味着我们没有消费,而是补充了储备,内容增加了。 结果应该是-70。 我的请求输出:30

我的要求:

SELECT day, 
       Abs(Sum(diffn)) AS totN 
FROM   (SELECT Date(datetime)              AS day, 
               Max(content) - Min(content) AS diffN 
        FROM   logs 
        WHERE  NAME = 'Foo' 
               AND datetime >= '2018-04-22 00:00:00' 
               AND datetime <= '2018-04-23 00:00:00' 
        GROUP  BY Date(datetime)) a 
GROUP  BY day; 

但是对于第二个示例,结果是 30 而不是 70,我不知道为什么... 我希望您能帮助我更改我的请求并考虑重新填充,以便我得到我想要的结果。

谢谢!

【问题讨论】:

  • 你在用什么mysqloracle??请只标记一个。
  • 我编辑了,对不起
  • 请编辑您的问题并向我们展示清晰的输入和输出。

标签: mysql sql database select


【解决方案1】:

您需要通过比较最高和最低值来确定前缀,包括时间(小时)。我在这里使用带有两个子查询的“CASE”函数。

也许您需要将年月日转换,因为我使用的是德语日期时间格式。

SET @datetime = '2018-04-22';

SELECT date(datetime) as day
    ,(CASE WHEN
     (SELECT content FROM logs WHERE date(datetime) = @datetime ORDER BY datetime LIMIT 1)
        >
     (SELECT content FROM logs WHERE date(datetime) = @datetime ORDER BY datetime desc LIMIT 1)
       THEN min(content) - max(content)
       ELSE max(content) - min(content) END) as diffN
    FROM logs 

    WHERE Name = 'Foo' AND date(datetime) = @datetime
    GROUP BY day(datetime)
    ORDER BY datetime
    ;

【讨论】:

    【解决方案2】:

    这应该可以完成工作:

    SELECT day(datetime) as day, max(content) - min(content) as diffN
    FROM logs 
    WHERE Name = 'Foo' 
    AND datetime >= '2018-04-23 00:00:00' 
    AND datetime <= '2018-04-24 00:00:00' 
    GROUP BY day(datetime) 
    

    另外,更改日期过滤器,它应该在 23 和 24 之间。

    【讨论】:

    • 没错,我不需要它,但是在更改之后,第二个示例的结果仍然是错误的。您知道如何以一种好的方式显示笔芯吗?过滤器仅用于示例,它们不具有代表性
    【解决方案3】:

    您可能需要建立第一个和最后一个日期时间及其相关内容。例如

    drop table if exists t;
    create table t (name varchar(3), dt datetime, content int);
    insert into t values
    ('Foo' , '2018-04-22 06:00:00', 120),
    ('Foo' , '2018-04-22 10:00:00', 119),
    ('Foo' , '2018-04-22 16:00:00', 118),
    ('Foo' , '2018-04-23 06:00:00', 50),
    ('Foo' , '2018-04-23 10:00:00', 90),
    ('Foo' , '2018-04-23 16:00:00', 120);
    
    select s.name,lastinday,firstinday,lastinday - firstinday
    from 
    (
    select name,dt, content lastinday
    from t
    where dt = (Select max(dt) from t t1 where t1.name = t.name and date(t1.dt) = date(t.dt))
    ) s
    join
    (
    select name,dt, content firstinday
    from t
    where dt = (Select min(dt) from t t1 where t1.name = t.name and date(t1.dt) = date(t.dt))
    ) t
    on t.name = s.name and date(t.dt) = date(s.dt);
    
    +------+-----------+------------+------------------------+
    | name | lastinday | firstinday | lastinday - firstinday |
    +------+-----------+------------+------------------------+
    | Foo  |       118 |        120 |                     -2 |
    | Foo  |       120 |         50 |                     70 |
    +------+-----------+------------+------------------------+
    2 rows in set (0.00 sec)
    

    【讨论】:

      【解决方案4】:

      为什么要第二次分组:

      理想情况下应该可以:

      SELECT Date(datetime)              AS day, 
             Max(content) - Min(content) AS diffN 
      FROM   logs 
      WHERE  NAME = 'Foo' 
             AND datetime >= '2018-04-22 00:00:00' 
             AND datetime <= '2018-04-23 00:00:00' 
      GROUP  BY Date(datetime) 
      

      此查询的结果将仅包含 2 行 - 第 22 天第 1 行,第 23 天第 1 行。不用再按天分组了

      【讨论】:

      • 没错,我不需要它,但是在更改之后,第二个示例的结果仍然是错误的。您知道如何以一种好的方式显示笔芯吗?
      • 尝试调试它。而不是在 max - min 上,也分别选择这些值并检查这是否是您想要的值。 SELECT date(datetime) as day, max(content) as max, min(content) as min, max(content) - min(content) as diffN
      • 谢谢拉胡尔,这是个好主意,我没想到。它显示第二个示例需要 90 和 120 而不是 50 和 120。它没有采用当天的最小值,这很奇怪......
      • 您可以尝试更多查询来调试:例如:尝试删除 where name='Foo' 条件或列出当天的所有值(不分组)。检查您是否获得了预期的结果。
      猜你喜欢
      • 1970-01-01
      • 2017-01-01
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 1970-01-01
      相关资源
      最近更新 更多