Bind rows based on status - sql

I have a table like:
logID eventID repID statusID logTime
174356 228985 107959 1 2013-05-03 09:25:41.000
174391 228985 107959 1 2013-05-03 10:06:33.000
174588 228985 107959 2 2013-05-03 14:59:51.000
I want the Output as
Date ClockIn ClockOut
05/03/2013 9:25:41 AM
05/03/2013 10:06:33 AM 2:59:51 PM
ie.. If the Status is 1 it has to be in ClockIn and if 2 in ClockOut.
But Iam getting the output as
Date ClockIn ClockOut
05/03/2013 9:25:41 AM 2:59:51 PM
05/03/2013 10:06:33 AM 2:59:51 PM
I have checked as if the status is 2 and if it is greater than clock in time, then it has to be displayed under clock out time...
My Query:
Select LTRIM(RIGHT(CONVERT(CHAR(20), rt.logTime, 22), 11)) as ClockIn,
LTRIM(RIGHT(CONVERT(CHAR(20), Min(rt1.logTime), 22), 11)) as ClockOut
from table1 rt
join table1 rt1 ON rt.repID = rt1.repID and rt1.statusID=2
AND CONVERT(nvarchar(25), rt.logTime,101) = CONVERT(nvarchar(25), rt1.logTime,101) AND rt.logTime<rt1.logTime
where rt.eventID='228985' and rt.repID='107959' and CONVERT(date, rt.logTime) = CONVERT(date, '05/03/2013')
group by rt.logTime, rt1.logTime
How should I get the desired result.........

Try this answer.
SELECT LTRIM(RIGHT(CONVERT(CHAR(20), rt.logTime, 22), 11)) AS ClockIn,
LTRIM(RIGHT(CONVERT(CHAR(20), Min(rt1.logTime), 22), 11)) AS ClockOut
FROM table1 rt
LEFT JOIN (
SELECT eventID,
repID,
CONVERT(DATE, logTime) LogTime,
MAX(logId) LogID
FROM table1
WHERE StatusID = 1
GROUP BY eventID,
repID,
CONVERT(DATE, logTime)
) rr
ON rt.LogId = rr.logId
LEFT JOIN table1 rt1
ON rr.repID = rt1.repID
AND rt1.statusID = 2
AND CONVERT(NVARCHAR(25), rr.logTime, 101) = CONVERT(NVARCHAR(25), rt1.logTime, 101)
AND rt.logTime < rt1.logTime
WHERE rt.StatusID = 1
AND rt.eventID = '228985'
AND rt.repID = '107959'
AND CONVERT(DATE, rt.logTime) = CONVERT(DATE, '05/03/2013')
GROUP BY rt.logTime,
rt1.logTime
Fiddle demo

Related

How can I get the count of inserts per minute in SQL

I have a table that looks like this
id
name
CreatedDate
1
test1
2014-06-30 09:00:00
1
test2
2014-06-30 09:01:10
1
test3
2014-06-30 09:01:23
1
test4
2014-06-30 09:01:43
1
test5
2014-06-30 09:02:02
1
test6
2014-06-30 09:02:34
1
test7
2014-06-30 09:03:22
1
test8
2014-06-30 09:03:28
1
test9
2014-06-30 09:04:14
1
test10
2014-06-30 09:04:22
1
test11
2014-06-30 09:04:28
I want to get the number of inserts that have happened per minute so the output looks like this
Inserts Per Min
Start Time
End Time
1
09:00:00
09:00:00
3
09:01:10
09:01:43
2
09:02:02
09:00:34
2
09:03:22
09:03:28
3
09:04:14
09:04:28
How can I do that?
This is the code that I have that gives me the Inserts per day but I can't get this to work per minute
Select Count(CreatedDate) as InsertsPerDay, Convert(varchar, CreatedDate, 101) as CreatedDate
From MyTable
Where DATEDIFF(day, CreatedDate, GETDATE())) < 30
Group By Convert(varchar, CreatedDate, 101)
Order By InsertsPerDay DESC
use subqueries and lag
declare #tmp as table(id int, name varchar(20), CreatedDate datetime)
insert into #tmp values(
1,'test1','2014-06-30 09:00:00')
,(1,'test2','2014-06-30 09:01:10')
,(1,'test3','2014-06-30 09:01:23')
,(1,'test4','2014-06-30 09:01:43')
,(1,'test5','2014-06-30 09:02:02')
,(1,'test6','2014-06-30 09:02:34')
,(1,'test7','2014-06-30 09:03:22')
,(1,'test8','2014-06-30 09:03:28')
,(1,'test9','2014-06-30 09:04:14')
,(1,'test1','2014-06-30 09:04:22')
,(1,'test11','2014-06-30 09:04:28')
select
IsNull(sum(case when Seconds between 0 and 60 then 1 end),0) Minute_One,
IsNull(sum(case when Seconds between 61 and 60*2 then 1 end),0) Minute_Two,
IsNull(sum(case when Seconds > 60*2 then 1 end),0) Minute_Others
from
(
select
(DATEPART(HOUR, DiffCreatedDate) * 3600) +
(DATEPART(MINUTE, DiffCreatedDate) * 60) +
(DATEPART(SECOND, DiffCreatedDate)) Seconds
from
(
select
CreatedDate-PriorCreatedDate DiffCreatedDate
from
(
select
CreatedDate,
lag(CreatedDate,1) over(order by CreatedDate) PriorCreatedDate
from #tmp
)x
)y
)z
--order by Seconds
DECLARE #Mytimes TABLE
(
id INT IDENTITY NOT NULL PRIMARY KEY,
name VARCHAR(10),
CreatedDate DATETIME
);
INSERT INTO #Mytimes
(
[name],
CreatedDate
)
VALUES
('test1', '2014-06-30 09:00:00'),
('test2', '2014-06-30 09:01:10'),
('test3', '2014-06-30 09:01:23'),
('test4', '2014-06-30 09:01:43'),
('test5', '2014-06-30 09:02:02'),
('test6', '2014-06-30 09:02:34'),
('test7', '2014-06-30 09:03:22'),
('test8', '2014-06-30 09:03:28'),
('test9', '2014-06-30 09:04:14'),
('test10', '2014-06-30 09:04:22'),
('test11', '2014-06-30 09:04:28');
WITH TALLY
AS (SELECT TOP (1440)
ROW_NUMBER() OVER (ORDER BY t1.object_id) AS N
FROM sys.all_columns t1
CROSS JOIN sys.all_columns t2),
ranges
AS (SELECT CAST(DATEADD(MINUTE, N - 1, '00:00') AS TIME(0)) AS [from],
CAST(DATEADD(MINUTE, N, '00:00') AS TIME(0)) AS [to]
FROM TALLY),
myTimes
AS (SELECT CAST(CreatedDate AS TIME(0)) ct
FROM #Mytimes)
--SELECT r.[from],
-- r.[to],
SELECT MIN(t.ct) [from],
MAX(t.ct) [to],
COUNT(t.ct)
FROM ranges r
-- If you want all minutes regardless there is inserts
--LEFT JOIN myTimes t
INNER JOIN myTimes t
ON t.ct >= r.[from]
AND t.ct < r.[to]
GROUP BY r.[from],
r.[to]
ORDER BY r.[from];
Note: In case of left join, you would need to edit the select to use coalesce for min(),max() times. ie:
...
SELECT MIN(COALESCE(t.ct, r.[from])) [from],
MAX(COALESCE(t.ct, r.[to])) [to],
COUNT(t.ct)
FROM ranges r
LEFT JOIN myTimes t
ON t.ct >= r.[from]
AND t.ct < r.[to]
GROUP BY r.[from],
r.[to]
ORDER BY r.[from];
This might work on 2008. (but can't verify)
Select
Count(CreatedDate) As [Inserts Per Min]
, Min(Cast(CreatedDate As Time(0))) As [Start Time]
, Max(Cast(CreatedDate As Time(0))) As [End Time]
From MyTable
--Where CreatedDate > DateAdd(month, -1, GetDate())
Group By Convert(SmallDateTime, Convert(Char(16), CreatedDate, 120))
Order By [Inserts Per Min] Desc;
Inserts Per Min
Start Time
End Time
3
09:01:10
09:01:43
3
09:04:14
09:04:28
2
09:02:02
09:02:34
2
09:03:22
09:03:28
1
09:00:00
09:00:00
Demo on db<>fiddle here

Get Last and Next Appointments

I have the following table in SQL Server and would like to get the last and next appointments for each customer.
Note: If the first appointment is in the future, last appointment should be N/A. Similarly if the last appointment is in the past, next appointment will be N/A. If the last appointment is older than 30 days it should not be shown (if there is no future appointment - considered an inactive customer).
CustomerId (int) | Date (date) | Time (time)
1 | 20210801 | 11:00
1 | 20210802 | 13:00
1 | 20210805 | 10:00
1 | 20210811 | 16:00
1 | 20210821 | 17:00
2 | 20210801 | 11:00
2 | 20210802 | 11:00
2 | 20210803 | 11:00
2 | 20210804 | 11:00
3 | 20210831 | 11:00
4 | 20210526 | 10:00
In this case the result should be (Assuming the date is today 7 August 2021):
CustomerId (int) | LastAppointment (varchar) | NextAppointment (varchar)
1 | 05 Aug 2021 - 10:00 | 11 Aug 2021 - 16:00
2 | 04 Aug 2021 - 11:00 | N/A
3 | N/A | 31 Aug 2021 - 11:00
Can anyone help me please? An example would be appreciated.
You simply need to work with datetime values and then use conditional aggregation to select the required date for each customer. Using a CTE first to simplify converting the dates as much as possible, this looks like:
with ap as (
select CustomerId, Convert(datetime,Left(Concat([date], ' ', [time]),15)) app
from t
), groups as (
select CustomerId,
Max(case when app <= GetDate() then app end) LastAppointment,
Min(case when app > GetDate() then app end) NextAppointment
from ap
group by customerId
)
select CustomerID,
IsNull(Format(LastAppointment, 'dd MMM yyyy - hh:mm'), 'N/A') LastAppointment,
IsNull(Format(NextAppointment, 'dd MMM yyyy - hh:mm'), 'N/A') NextAppointment
from groups
where DateAdd(day,-30,GetDate()) < isnull(lastappointment,GetDate())
see DB<>Fiddle
Also note this query only touches the table once and performs a single logical read.
You need conditional aggregation:
SELECT CustomerId,
COALESCE(
MAX(CASE
WHEN CAST(Date AS DATETIME) + CAST(Time AS DATETIME) < GETDATE()
THEN FORMAT(CAST(Date AS DATETIME) + CAST(Time AS DATETIME), 'dd MMM yyyy - HH:mm')
END
), 'N/A'
) LastAppointment,
COALESCE(
MIN(CASE
WHEN CAST(Date AS DATETIME) + CAST(Time AS DATETIME) > GETDATE()
THEN FORMAT(CAST(Date AS DATETIME) + CAST(Time AS DATETIME), 'dd MMM yyyy - HH:mm')
END
), 'N/A'
) NextAppointment
FROM tablename
GROUP BY CustomerId
HAVING COALESCE(DATEDIFF(
d,
MAX(CASE
WHEN CAST(Date AS DATETIME) + CAST(Time AS DATETIME) < GETDATE()
THEN CAST(Date AS DATETIME) + CAST(Time AS DATETIME)
END
),
GETDATE()
), 0) < 30
See the demo.
Results:
CustomerId
LastAppointment
NextAppointment
1
05 Aug 2021 - 10:00
11 Aug 2021 - 16:00
2
04 Aug 2021 - 11:00
N/A
3
N/A
31 Aug 2021 - 11:00
NOTE : This solution works but it is very bad in terms of performance, check this answer for a better approach
Something like this
SELECT DISTINCT customerid,
Isnull(CONVERT(VARCHAR,
(SELECT TOP 1 Concat(date, ' ', TIME)
FROM appointments B
WHERE b.customerid = a.customerid
AND ([date] < CONVERT(DATE, Getdate())
OR ([date] = CONVERT(DATE, Getdate())
AND [time] <= CONVERT(TIME, Getdate())))
ORDER BY [date] DESC)), 'N/A') AS lastappointment,
Isnull(CONVERT(VARCHAR,
(SELECT TOP 1 Concat(date, ' ', TIME)
FROM appointments B
WHERE b.customerid = a.customerid
AND ([date] > CONVERT(DATE, Getdate())
OR ([date] = CONVERT(DATE, Getdate())
AND [time] > CONVERT (TIME, Getdate())))
ORDER BY [date])), 'N/A') AS nextappointment
FROM appointments A
WHERE Datediff(DAY,
(SELECT TOP 1 date
FROM appointments B
WHERE b.customerid = a.customerid
AND [date] <= CONVERT(DATE, Getdate())
ORDER BY [date] DESC), CONVERT(DATE, Getdate())) <= 30
OR (((
(SELECT TOP 1 date
FROM appointments B
WHERE b.customerid = a.customerid
AND [date] > CONVERT(DATE, Getdate())
ORDER BY [date]) > CONVERT(DATE, Getdate())))
OR ((
(SELECT TOP 1 date
FROM appointments B
WHERE b.customerid = a.customerid
AND [date] > CONVERT(DATE, Getdate())
ORDER BY [date]) = CONVERT(DATE, Getdate()))
AND (
(SELECT TOP 1 [time]
FROM appointments B
WHERE b.customerid = a.customerid
AND [date] > CONVERT(DATE, Getdate())
ORDER BY [date]) > CONVERT(TIME, Getdate()))))
I called your table appointments and the condition is to select customer with last appointment in the past 30 days OR with a future appointment.
I tested with column types Date for Date and Time(7) for time.
Base table is used only single time because of optimization purpose. Use LAG() function and others necessary condition for picking actual set of data.
-- SQL SERVER
SELECT p.CustomerId
, CASE WHEN p.chk_condition = 1
THEN CONVERT(varchar(13), p.prev_Date, 113) + ' - ' + LEFT(p.prev_time, 5)
WHEN p.chk_condition = 2
THEN CONVERT(varchar(13), p.Date, 113) + ' - ' + LEFT(p.time, 5)
ELSE 'N/A'
END "LastAppointment"
, CASE WHEN p.chk_condition != 2
THEN CONVERT(varchar(13), p.Date, 113) + ' - ' + LEFT(p.time, 5)
ELSE 'N/A'
END "NextAppointment"
FROM ( SELECT t.*
, CASE WHEN t.prev_Date < GETDATE() AND t.Date >= GETDATE()
THEN 1
WHEN t.prev_Date < GETDATE() AND t.Date <= GETDATE()
THEN 2
ELSE 0
END chk_condition
, ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY t.Date DESC, t.prev_Date DESC) row_num
FROM (SELECT CustomerId, Date, Time
, LAG(Date) OVER (PARTITION BY CustomerId ORDER BY "Date", "Time") "prev_Date"
, LAG(Time) OVER (PARTITION BY CustomerId ORDER BY "Date", "Time") "prev_Time"
FROM appointment) t
WHERE CASE WHEN t.prev_Date < GETDATE() AND t.Date >= GETDATE()
THEN 1
WHEN t.prev_Date IS NULL
THEN CASE WHEN DATEDIFF(day, t.Date, GETDATE()) >= 30
THEN 0
ELSE 1
END
WHEN t.prev_Date < GETDATE() AND t.Date <= GETDATE()
THEN 1
END = 1 ) p
WHERE p.row_num = 1
ORDER BY p.CustomerId;
Please check this url https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=3813d09cf25ed14d249970654995b085

How to modify my SQL to select values that match dates across different rows?

I have the following query (SQL Server):
select a.Booking_Type, b.Unit_Code, a.Start_Date, a.End_Date
from Booking a
inner join Property b
on a.Property_ID = b.Property_ID
where a.Agency_ID = 1020 and
b.IsEnabled = 1 and
a.Hold_Agreement_Signed is null and
(convert(varchar(10), a.Start_Date, 102) = convert(varchar(10), getdate(), 102) or convert(varchar(10), a.End_Date, 102) = convert(varchar(10), getdate()-1, 102))
my results from this query look like:
Booking_Type Unit_Code Start_Date End_Date
0 448 2014-09-22 00:00:00 2014-09-28 00:00:00
0 448 2014-09-21 05:00:00 2014-09-21 05:00:00
0 K187 2014-09-19 00:00:00 2014-09-21 00:00:00
0 K187 2014-09-18 00:00:00 2014-09-21 00:00:00
What I am looking to get is a single row with Unit_Code = 448 because it has a row with a Start_Date of today and a row with an End_Date of yesterday (there was a checkout yesterday and a checkin today).
How do I modify my query to obtain this?
you will need to join a second instance of Booking:
select a.Booking_Type, b.Unit_Code, a.Start_Date, a.End_Date
from Booking inner join Property b a.Property_ID = b.Property_ID
inner join Booking b1
on a.Property_ID = b1.Property_ID
and convert your where condition from OR to AND
... convert(varchar(10), a.Start_Date, 102) = convert(varchar(10), getdate(), 102)
**AND**
convert(varchar(10), **B1**.End_Date, 102) = convert(varchar(10), getdate()-1, 102))
If you just want to return the Unit_Code that meets your date criteria, you should use HAVING:
select b.Unit_Code
from Booking a
inner join Property b
on a.Property_ID = b.Property_ID
where a.Agency_ID = 1020
and b.IsEnabled = 1
and a.Hold_Agreement_Signed is null
GROUP BY b.Unit_Code
HAVING MAX(CASE WHEN CAST(a.Start_Date AS DATE) = CAST(GETDATE() AS DATE) THEN 1 END) = 1
AND MAX(CASE WHEN CAST(a.End_Date AS DATE) = CAST(GETDATE()-1 AS DATE) THEN 1 END) = 1

Add all the rows of a column and store in another column

I am using this query and the result of it is as:
SELECT
t.TestId,
t.Days,
t.FullName
[Date] = Convert(date,DATEADD(dd, 0, DATEDIFF(dd, 0, t.CheckIn))),
CheckIn = CONVERT(CHAR(5), t.CheckIn, 108),
CheckOut = CONVERT(CHAR(5), t.CheckOut, 108),
[Hours] = CAST(DATEDIFF(MINUTE, t.CheckIn, t.CheckOut) / 60. AS DECIMAL(10,2))
FROM (
SELECT
FullName = Users.FullName,
TestId = t.TestId,
Days = t.Days,
t.UserId_Fk,
CheckIn = t.CheckInTime,
CheckOut = r.CheckInTime,
RowNum = ROW_NUMBER() OVER (PARTITION BY t.UserId_Fk, r.CheckInTime ORDER BY 1/0)
FROM UserTime t
INNER JOIN Users
ON t.UserId_Fk=Users.UserId
OUTER APPLY (
SELECT TOP 1 *
FROM UserTime t2
WHERE
t2.CheckInTime > t.CheckInTime
AND DATEADD(dd, 0, DATEDIFF(dd, 0, t.CheckInTime)) = DATEADD(dd, 0, DATEDIFF(dd, 0, t2.CheckInTime))
AND t2.LoginStatus = 'O'
ORDER BY t2.CheckInTime
) r
WHERE t.LoginStatus = 'I'
) t
WHERE t.RowNum = 1
Result:
TestId Days FullName Date CheckIn CheckOut Hours
11 Wednesday Antonio 2014-05-14 10:19 10:20 0.02
13 Wednesday Antonio 2014-05-14 10:19 10:20 0.02
14 Wednesday Tim 2014-05-14 10:20 10:21 0.02
Table Structure:
Table UserTime:
TestId int(pk)
UserId_Fk int
Days nvarchar(50)
Date date
CheckInTime datetime
LoginStatus char(1)
Table Users:
UserId int(Pk)
FullName varchar(50)
I want a column named TotalHours which Adds All the fields of Hours Column and Display the value.
Somewhat like this:
TestId Days FullName Date CheckIn CheckOut Hours TotalHours
11 Wednesday Antonio 2014-05-14 10:19 10:20 0.02 0.04
11 Wednesday Antonio 2014-05-14 10:19 10:20 0.02
13 Wednesday Tim 2014-05-14 10:20 10:21 0.02
You should have two queries in the left query sum the total hours and in the right select the required column then join the queries.
select * from
(SELECT testid,sum(Hours) as total from(
SELECT
t.TestId,
t.FullName ,
[Hours] = CAST(DATEDIFF(MINUTE, t.CheckIn, t.CheckOut) / 60. AS DECIMAL(10,2))
FROM (
SELECT
FullName = Users.FullName,
TestId = t.TestId,
Days = t.Days,
t.UserId_Fk,
CheckIn = t.CheckInTime,
CheckOut = r.CheckInTime,
RowNum = ROW_NUMBER() OVER (PARTITION BY t.UserId_Fk, r.CheckInTime ORDER BY 1/0)
FROM UserTime t
INNER JOIN Users
ON t.UserId_Fk=Users.UserId
OUTER APPLY (
SELECT TOP 1 *
FROM UserTime t2
WHERE
t2.CheckInTime > t.CheckInTime
AND DATEADD(dd, 0, DATEDIFF(dd, 0, t.CheckInTime)) = DATEADD(dd, 0, DATEDIFF(dd, 0, t2.CheckInTime))
AND t2.LoginStatus = 'O'
ORDER BY t2.CheckInTime
) r
WHERE t.LoginStatus = 'I'
) t
WHERE t.RowNum = 1
)s
group by s.FullName,testid)O
INNER JOIN
(
SELECT
t.TestId,
t.Days,
t.FullName ,
[Date] = Convert(date,DATEADD(dd, 0, DATEDIFF(dd, 0, t.CheckIn))),
CheckIn = CONVERT(CHAR(5), t.CheckIn, 108),
CheckOut = CONVERT(CHAR(5), t.CheckOut, 108),
[Hours] = CAST(DATEDIFF(MINUTE, t.CheckIn, t.CheckOut) / 60. AS DECIMAL(10,2))
FROM (
SELECT
FullName = Users.FullName,
TestId = t.TestId,
Days = t.Days,
t.UserId_Fk,
CheckIn = t.CheckInTime,
CheckOut = r.CheckInTime,
RowNum = ROW_NUMBER() OVER (PARTITION BY t.UserId_Fk, r.CheckInTime ORDER BY 1/0)
FROM UserTime t
INNER JOIN Users
ON t.UserId_Fk=Users.UserId
OUTER APPLY (
SELECT TOP 1 *
FROM UserTime t2
WHERE
t2.CheckInTime > t.CheckInTime
AND DATEADD(dd, 0, DATEDIFF(dd, 0, t.CheckInTime)) = DATEADD(dd, 0, DATEDIFF(dd, 0, t2.CheckInTime))
AND t2.LoginStatus = 'O'
ORDER BY t2.CheckInTime
) r
WHERE t.LoginStatus = 'I'
) t
WHERE t.RowNum = 1
)I
on i.testid=o.testid

How to display the calculated value only one time using sql query

I have the following query :
`
select e.empid, convert(char(5), tr.In_Time, 108) as In_time,
convert(char(5), tr.Out_Time, 108) as Out_time,
convert(varchar(5), sum(datediff(minute, trr.In_Time, isnull(trr.Out_Time, null))) / 60)
+ ':' +
convert(varchar(5),sum(datediff(minute, trr.In_Time, isnull(trr.Out_Time,null))) % 60)
as TotalHours,
from EMPLOYEES e
Left Join EMPLOYEE_TIME tr
on (e.empid=tr.empid)
Left Join EMPLOYEE_TIME trr
on (e.empid=trr.empid)
where (
trr.In_Time BETWEEN '2013-09-11' AND DATEADD(DAY, 1, '2013-09-11')
and tr.In_Time BETWEEN '2013-09-11' AND DATEADD(DAY, 1, '2013-09-11')
) group by e.empid, tr.In_Time, tr.Out_Time e.JoiningDate order by e.JoiningDate ASC
`
After executing above query, i get the following result :
`
EmpID in_time out_time totalhours
1 9:30 18:00 8:30
2 10:00 13:00 8:00
2 14:00 19:00
3 10:30 13:30 3:00
3 14:30 NULL 3:00
`
But i don't want to print the totalhours twice when multiple time entry Out_time is Null, as like below :
`
EmpID in_time out_time totalhours
1 9:30 18:00 8:30
2 10:00 13:00 8:00
2 14:00 19:00
3 10:30 13:30 3:00
3 14:30 NULL
`
Could anybody please help me? thanks in advance
WORKING SQL
SELECT e.empid ,
CONVERT(CHAR(5), tr.In_Time, 108) AS In_time ,
CONVERT(CHAR(5), tr.Out_Time, 108) AS Out_time ,
CONVERT(VARCHAR(5), SUM(DATEDIFF(minute, trr.In_Time,
ISNULL(trr.Out_Time, NULL))) / 60)
+ ':' + CONVERT(VARCHAR(5), SUM(DATEDIFF(minute, trr.In_Time,
ISNULL(trr.Out_Time, NULL)))
% 60) AS TotalHours
FROM EMPLOYEES e
LEFT JOIN EMPLOYEE_TIME tr ON ( e.empid = tr.empid )
LEFT JOIN EMPLOYEE_TIME trr ON ( e.empid = trr.empid )
WHERE ( trr.In_Time BETWEEN '2013-09-11'
AND DATEADD(DAY, 1, '2013-09-11')
AND tr.In_Time BETWEEN '2013-09-11'
AND DATEADD(DAY, 1, '2013-09-11')
)
GROUP BY e.empid ,
tr.In_Time ,
tr.Out_Time ,
e.JoiningDate
ORDER BY e.JoiningDate ASC
JUST USE CASE WHEN
LIKE
CASE WHEN Out_Time IS NOT NULL THEN convert(varchar(5),sum(datediff(minute, trr.In_Time, isnull(trr.Out_Time,null))) % 60)
ELSE NULL END
Based on your example, it seems that you only want the hours on the first row for each EmpID. (If not, please update the question with additional data that are exceptions to this.)
Assuming this, here is a method using row_number():
with yourquery as (<your query here>)
select EmpID, in_time, out_time,
(case when seqnum = 1 then totalhours end) as totalhours
from (select yq.*,
row_number() over (partition by EmpId order by in_time) as seqnum
from yourquery yq
) yq;
EDIT:
This is what it should look like:
with yourquery as (
SELECT e.empid ,
CONVERT(CHAR(5), tr.In_Time, 108) AS In_time ,
CONVERT(CHAR(5), tr.Out_Time, 108) AS Out_time ,
CONVERT(VARCHAR(5), SUM(DATEDIFF(minute, trr.In_Time,
ISNULL(trr.Out_Time, NULL))) / 60)
+ ':' + CONVERT(VARCHAR(5), SUM(DATEDIFF(minute, trr.In_Time,
ISNULL(trr.Out_Time, NULL)))
% 60) AS TotalHours
FROM EMPLOYEES e
LEFT JOIN EMPLOYEE_TIME tr ON ( e.empid = tr.empid )
LEFT JOIN EMPLOYEE_TIME trr ON ( e.empid = trr.empid )
WHERE ( trr.In_Time BETWEEN '2013-09-11'
AND DATEADD(DAY, 1, '2013-09-11')
AND tr.In_Time BETWEEN '2013-09-11'
AND DATEADD(DAY, 1, '2013-09-11')
)
GROUP BY e.empid ,
tr.In_Time ,
tr.Out_Time ,
e.JoiningDate
)
select yq.EmpID, yq.in_time, yq.out_time,
(case when seqnum = 1 then yq.totalhours end) as totalhours
from (select yq.*,
row_number() over (partition by yq.EmpId order by in_time) as seqnum
from yourquery yq
) yq
ORDER BY yq.JoiningDate ASC