Запрос вычитать одно и то же значение столбца в разные интервалы дня с базой данных SQL - PullRequest
1 голос
/ 27 мая 2019

В MySQL я хочу вычесть одно из значений столбца в другой интервал времени на основе другого столбца 'timestamp'.

table structure is : 
id | generator_id | timestamp             | generated_value
1  |  1           | 2019-05-27 06:55:20   | 123456     
2  |  1           | 2019-05-27 07:55:20   | 234566       
3  |  1           | 2019-05-27 08:55:20   | 333456       
..
..    
20  |  1           | 2019-05-27 19:55:20   | 9876908       

Из приведенной выше таблицы я хочу получить значение столбца generate_value, которое должно быть разностью первой отметки времени дня и отметки времени последнего значения дня.

В приведенном выше примере я ищу запрос, который должен дать мне вывод 9 753 452 (9876908 - 123456).

В общем, чтобы получить одну запись первого значения и последнего значения дня, который я использую ниже запроса

// Below will give me end day value
SELECT * FROM generator_meters where generator_id=1 and timestamp like '2019-05-27%' order by timestamp desc limit 1 ;

//this will give me last day value 
SELECT * FROM generator_meters where generator_id=1 and timestamp like '2019-05-27%' order by timestamp  limit 1 ;

Вопрос в том, как мне получить окончательное значение_произведенного, выполнив минус первого значения дня от последнего значения дня.

Expected Output 
 generator_id | generated_value
  1           | 9753452     

Спасибо заранее !!

Ответы [ 2 ]

1 голос
/ 27 мая 2019

В вашем примере значение становится все больше и больше. Если это гарантированно так, вы можете использовать

select max(generated_value) - min(generated_value) as result
from sun_electric.generator_meters
where generator_id = 1
and date(timestamp) = date '2019-05-27';

или для нескольких идентификаторов:

select generator_id, max(generated_value) - min(generated_value) as result
from sun_electric.generator_meters
and date(timestamp) = date '2019-05-27'
group by generator_id
order by generator_id;

Если значение не по возрастанию, то для идентификатора 1 можно использовать следующий запрос:

select last_row.generated_value - first_row.generated_value as result
from 
(
  select * 
  from sun_electric.generator_meters
  where generator_id = 1
  and date(timestamp) = date '2019-05-27'
  order by timestamp
  limit 1
) first_row
cross join
(
  select * 
  from sun_electric.generator_meters
  where generator_id = 1
  and date(timestamp) = date '2019-05-27'
  order by timestamp desc
  limit 1
) last_row;

Вот один из способов получить результат для нескольких идентификаторов:

select
  minmax.generator_id,
  (
    select generated_value 
    from sun_electric.generator_meters gm
    where gm.generator_id = minmax.generator_id
    and gm.timestamp = minmax.max_ts
  ) -
  (
    select generated_value 
    from sun_electric.generator_meters gm
    where gm.generator_id = minmax.generator_id
    and gm.timestamp = minmax.min_ts
  ) as result
from
(
  select generator_id, min(timestamp) as min_ts, max(timestamp) as max_ts
  from sun_electric.generator_meters
  where date(timestamp) = date '2019-05-27'
  group by generator_id
) minmax
order by minmax.generator_id;

Вы также можете переместить подзапросы в предложение from и присоединиться к ним, если вам это нравится больше. Еще один подход заключается в использовании оконных функций, доступных с MySQL 8.

1 голос
/ 27 мая 2019

Этот следующий скрипт вернет ожидаемые результаты для отфильтрованного идентификатора и даты -

SELECT generator_id,CAST(timestamp AS DATE) ,
(
    SELECT generated_value 
    FROM sun_electric.generator_meters B 
    WHERE timestamp = max(timestamp)
)
-
(
    SELECT generated_value 
    FROM sun_electric.generator_meters B 
    WHERE timestamp = min(timestamp)
) AS Diff
FROM sun_electric.generator_meters 
WHERE generator_id = 1
AND CAST(timestamp AS DATE) = '2019-05-27'
GROUP BY generator_id,CAST(timestamp AS DATE) ; 

Если вы хотите получить тот же результат, что и для GROUP BY ID и даты, просто удалите фильтр, как показано ниже -

SELECT generator_id,CAST(timestamp AS DATE) ,
(
    SELECT generated_value 
    FROM sun_electric.generator_meters B 
    WHERE timestamp = max(timestamp)
)
-
(
    SELECT generated_value 
    FROM sun_electric.generator_meters B 
    WHERE timestamp = min(timestamp)
) AS Diff
FROM sun_electric.generator_meters 
GROUP BY generator_id,CAST(timestamp AS DATE) ;     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...