简体   繁体   中英

how to sum time and handle null value using case in sql server

i want the result in single row, GROUP BY sys_service_id,stat.---------------

SELECT sys_service_id,
  CASE WHEN stat='Idle' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end  AS 'Idle', 

  CASE WHEN stat='Long Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else ''  end  AS 'Long Halt', 

  CASE WHEN stat='Short Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end AS 'Short Halt',

  CASE WHEN stat='Running' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end AS 'Running'
  FROM testing1 GROUP BY sys_service_id,stat

but, this given result as follows:-

sys_service_id  Idle           Long Halt         Short Halt     Running
2823    00:33:12.0000000    00:00:00.0000000 00:00:00.0000000   00:00:00.0000000
2823    00:00:00.0000000    10:56:19.0000000 00:00:00.0000000   00:00:00.0000000
2823    00:00:00.0000000    00:00:00.0000000 00:00:00.0000000   01:03:13.0000000
2823    00:00:00.0000000    00:00:00.0000000 00:18:48.0000000   00:00:00.0000000

i want as :-

sys_service_id  Idle           Long Halt         Short Halt     Running
2823    00:33:12.0000000    10:56:19.0000000 00:18:48.0000000   01:03:13.0000000

A simple MAX clause can give you the desired results

SELECT 
  sys_service_id,
  MAX(CASE WHEN stat='Idle' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else NULL end)  AS 'Idle', 

  MAX(CASE WHEN stat='Long Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else NULL  end ) AS 'Long Halt', 

  MAX(CASE WHEN stat='Short Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else NULL end) AS 'Short Halt',

  MAX(CASE WHEN stat='Running' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else NULL end) AS 'Running'

  FROM testing1 
GROUP BY sys_service_id,stat

First, don't include Stat in your group by clause, because you want a single record for multiple values of it.

Second, wrap your cases with a MAX function :

SELECT sys_service_id,
       MAX(CASE WHEN stat='Idle' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end)  AS 'Idle', 
       MAX(CASE WHEN stat='Long Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else ''  end)  AS 'Long Halt', 
       MAX(CASE WHEN stat='Short Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end) AS 'Short Halt',
       MAX(CASE WHEN stat='Running' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end) AS 'Running'
FROM testing1 
GROUP BY sys_service_id

EDIT:

SELECT t.sys_service_id,
       MAX(t.Idle),
       ...
FROM(
    SELECT sys_service_id,
           CASE WHEN stat='Idle' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end)  AS 'Idle', 
           CASE WHEN stat='Long Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else ''  end)  AS 'Long Halt', 
           CASE WHEN stat='Short Halt' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end) AS 'Short Halt',
           CASE WHEN stat='Running' THEN cast(dateadd(millisecond,sum(datediff(millisecond,0,cast(trip_leg as datetime))),0) as time) else '' end) AS 'Running'
    FROM testing1 
    GROUP BY sys_service_id,stat) t
GROUP BY t.sys_service_id

You want conditional aggregation. Move the case inside the sum() . . . and remove stat from the group by :

SELECT sys_service_id,
       cast(dateadd(millisecond,
                    sum(datediff(millisecond, 0,
                                 cast(case when stat = 'Idle' then trip_leg end as datetime)
                                )
                       ),
                       0) as time
           ) as Idle,

       cast(dateadd(millisecond,
                    sum(datediff(millisecond, 0,
                                 cast(case when stat = 'Long Halt' then trip_leg end as datetime)
                                )
                       ),
                    0) as time
           ) as [Long Halt],

       cast(dateadd(millisecond,
                    sum(datediff(millisecond, 0,
                                 cast(case when stat = 'Short Halt' then trip_leg end as datetime)
                                )
                       ),
                    0) as time
           ) as [Short Halt],

       cast(dateadd(millisecond,
                    sum(datediff(millisecond, 0,
                                 cast(case when stat = 'Running' then trip_leg end as datetime)
                                )
                       ),
                    0) as time
           ) as Running
FROM testing1
GROUP BY sys_service_id;

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