简体   繁体   中英

SQL query (MAX-MIN) is showing wrong results

I am trying to calculate data from my database but first I've noticed strange behavior from the results I get, second, I have trouble making a request that take into account refills.

I have a table with : Name - DateTime - content

I want to group by day the rows and select the difference of the number to have the consumption. For example :

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

The content has decreased, the result should be -2. Output of my request = -2

Another example :

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

Here we can notice that the number has increased. It means that instead of a consumption, we have refilled the reserve and the content has increased. The result should be -70. Output of my request : 30

My request :

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; 

But for the second example I have 30 as a result instead of 70, I don't know why... I would like your help to change my request and take refills into account so that I get the results I want.

Thanks!

You need to determine the Prefix by comparing the highest and the lowest value, the time (hour) included. I'm using the 'CASE' function with two subqueries here.

Maybe you'll need to turn the year-month-day around, because I'm using the german datetime-format.

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
    ;

Why are you grouping it second time:

Ideally this should work:

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) 

Result of this query will contain only 2 rows - 1 for 22th and 1 for 23rd day. There is no need of grouping it again by day

This should do the job:

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) 

Also, change the date filters it should be betweeen 23 and 24.

It might be that you need to establish the first and last datetime and their associated content. For example

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM