简体   繁体   中英

How to get a SUM of a DATEDIFF but provide cut-off at 24 hours IF a single day is specified

This is actually my first question on stackoverflow, so I sincerely apologize if I am confusing or unclear.

That being said, here is my issue:

I work at a car manufacturing company and we have recently implemented the ability to track when our machines are idle. This is done by assessing the start and end time of the event called "idle_start."

Right now, I am trying to get the SUM of how long a machine is idle. Now, I figured this out BUT, some of the idle_times are LONGER than 24 hours.

So, when I specify that I only want to see the idle_time sums of ONE particular day, the sum is also counting the idle time past 24 hours.

I want to provide the option of CUTTING OFF at that 24 hours. Is this possible?

Here is the query:

{code}

SELECT  r.`name` 'Producer'
     ,  m.`name` 'Manufacturer'
      -- , timediff(re.time_end, re.time_start) 'Idle Time Length'
      , SEC_TO_TIME(SUM((TIME_TO_SEC(TIMEDIFF(re.time_end, re.time_start))))) 'Total Time'
      , (SUM((TIME_TO_SEC(TIMEDIFF(re.time_end, re.time_start)))))/3600 'Total Time in Hours'
      , (((SUM((TIME_TO_SEC(TIMEDIFF(re.time_end, re.time_start)))))/3600))/((IF(r.resource_status_id = 2, COUNT(r.resource_id), NULL))*24) 'Percent Machine is Idle divided by Machine Hours'
 FROM resource_event re 
 JOIN resource_event_type ret
   ON re.resource_event_type_id  = ret.resource_event_type_id
 JOIN resource_event_type reep
   ON ret.parent_resource_event_type_id = reep.resource_event_type_id
 JOIN resource r
   ON r.`resource_id` = re.`resource_id`  
 JOIN manufacturer m
   ON m.`manufacturer_id` = r.`manufacturer_id`
WHERE re.`resource_event_type_id` = 19
  AND ret.`parent_resource_event_type_id` = 3
  AND DATE_FORMAT(re.time_start, '%Y-%m-%d') >= '2013-08-12'
   AND DATE_FORMAT(re.time_start, '%Y-%m-%d') <= '2013-08-18'
 -- AND re.`resource_id` = 8
  AND "Idle Time Length" IS NOT NULL
  AND  r.manufacturer_id = 13
  AND r.resource_status_id = 2
GROUP BY 1, 2

Feel free to ignore the dash marks up top. And please tell me if I can be more specific as to figure this out easier and provide less headaches for those willing to help me out.

Thank you so much!

You'll want a conditional SUM , using CASE .

Not sure of syntax for your db exactly, but something like:

, SUM (CASE WHEN TIME_TO_SEC(TIMEDIFF(re.time_end, re.time_start))/3600 > 24 THEN 0
            ELSE TIME_TO_SEC(TIMEDIFF(re.time_end, re.time_start))/3600
       END)'Total Time in Hours'

This is not an attempt to answer your question. It's being presented as an answer rather than a comment for better formatting and readability.

You have this

AND DATE_FORMAT(re.time_start, '%Y-%m-%d') >= '2013-08-12'
AND DATE_FORMAT(re.time_start, '%Y-%m-%d') <= '2013-08-18'

in your where clause. Using functions like this make your query take longer to execute, especially on indexed fields. Something like this would run quicker.

AND re.time_start >= a date value goes here
AND re.time_start <= another date value goes here

Do you want to cut off when start/end are before/after your time range?

You can use a case to adjust it based on your timeframe, eg for time_start

case
  when re.time_start < timestamp '2013-08-12 00:00:00' 
    then timestamp '2013-08-12 00:00:00' 
  else re.time_start
end

similar for time_end and then use those CASEs within your TIMEDIFF.

Btw, your where-condition for a given date range should be:

where time_start < timestamp '2013-08-19 00:00:00'
  and time_end >= timestamp '2013-08-12 00:00:00'

This will return all idle times between 2013-08-12 and 2013-08-18

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