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.