Calculate the datediff() between the date 1 and 2 - sql-server

I need to calculate the datediff from one column where the in time marked with a 1 and the out time marked with a 2. if an employee swiped in and there is no out or out but there was no in i would like it to show as null.
I am not sure how I go about doing this.
SELECT
u.userid
,et.name
,CASE
WHEN scs.FullName is NULL THEN u.name
WHEN scs.FullName is NOT NULL THEN scs.FullName
END AS name
,e.LoggedTime AS SwipeTime
,CASE
WHEN et.name = 'Output On By Door' OR et.name = 'User Granted
Entry To Door Using Reading Device' THEN 1
ELSE 2
END AS SwipeTimeDiff
,d.name AS Door
FROM [Users] AS u
LEFT JOIN [Events] AS e ON e.RecordIndex1=u.UserID
LEFT JOIN [EventTypes] AS et on e.EventTypeID = et.EventTypeID
join .[Doors] AS d ON e.RecordIndex2 = d.DoorID
LEFT join SecurityContractorSignIn as scs on scs.Badge = u.lastname
WHERE LoggedTime > CONVERT(DATE, GETDATE()) and d.doorid in (32, 50, 42, 51, 33)
ORDER BY u.name,e.LoggedTime DESC
I would like to have a computed column with the time difference in days, hours and minutes or null if if there is a missing in(1) or out(2) time.

Well, the DATEDIFF() function is fully explained here and the difference for the specific datepart you want to extract is returned as an integer.
According to your need you may do something like but you will have the information in three (or more - if you want to extend) different columns:
-- Calculate the difference of how many days have passed
SELECT DATEDIFF(DAY, LoginTime, LogoutTime) AS DaysPassed
-- Calculate the difference of how many hours have passed
SELECT DATEDIFF(HOUR, LoginTime, LogoutTime) AS HoursPassed
-- Calculate the difference of how minutes have passed
SELECT DATEDIFF(MINUTE, LoginTime, LogoutTime) AS MinutesPassed
If you want to return a string whether the employee logged out or not you may use something like:
SELECT ISNULL(CONVERT(nvarchar(50), DATEDIFF(MONTH, '2019-01-04', NULL)), 'No logout')

Related

SUM datetime value by month

I am working on a project for an organisation which handles tickets. I am doing this with SQL Management Studio. They want to know how much time they spend for each customer per month. What I have at the moment is individual tickets for each customer. Somehow I need to add these values by month an show in seperate column.
The column EndTime has the total time spend for each ticket, now I want to add these values for each month.
SELECT
[dbo].[Company].Name as CompanyName
, convert(time(0), CAST(EndTime AS TIME)) AS 'Worked hours'
,EndTime
,Category.Name as CategoryName
FROM [plugin.tickets].[Ticket]
LEFT JOIN [dbo].Category ON Category.Id = [plugin.tickets].Ticket.CategoryId
LEFT JOIN [plugin.tickets].TicketActivity ON TicketActivity.TicketId = [plugin.tickets].Ticket.Id
LEFT JOIN [dbo].Activity ON Activity.Id = [TicketActivity].ActivityId
LEFT JOIN [dbo].Company ON Company.Id = [plugin.tickets].Ticket.CompanyId
where
[plugin.tickets].[Ticket].status <= 2
AND [plugin.tickets].[Ticket].TypeId = 6 or [plugin.tickets].[Ticket].TypeId = 11
AND [dbo].Category.Name != 'VoIP Telefoni' AND [dbo].Category.Name != 'Beheer'
-- AND [dbo].Activity.EndTime is not null
-- AND DATEDIFF(MINUTE, CAST('00:00:00' AS TIME), CAST(EndTime AS TIME)) > 0
GROUP BY
[dbo].[Company].Name
,EndTime
,EndTime
,Category.Name
ORDER BY
'Worked hours' desc

how to use count, case and Distinct together in sql server

I want to create a statement but i not success to complete this. can you please take a look and let me know what i need to do to complete this. My problem due how to add these two part in my query.
I want to look at the last 30 days of orders for each DRV1NUM. If that driver has worked 0 days then say ‘NOT ACTIVE’. If the driver has worked more than 15 days then ‘FULL TIME’ and less than 15 days is ‘PART TIME’.
In this one, I want to look at the last 30 days of orders and compare the left(4) of DRIVERNUM to the entire DRIVERNUM. In some instances, we have drivers where there is a 5th letter after the left 4.I want to look at the last 30 days of orders and if the left(4) DRV1NUM has more than one DRV1NUM WHEN looking at all characters, then SAY ‘MASTER’
SELECT DISTINCT DRVLICNUM,DOB,COUNTRY,CREDITLIMIT,DRIVERNUM=LEFT(DRIVERNUM,4),
SSN,D.VEHICLE,PHN1,DRVLICST,HOST,VEHICLE_MC,
VEHICLE_DOT,BACK_APPROVED=CASE WHEN PROBDATE IS NOT NULL THEN 'YES' ELSE 'NO' END
-- CASE WHEN COUNT(DISTINCT O.DROPDATE)=0 IN LAST 30 DAYS THEN 'NOT ACTIVE' WHEN COUNT(DISTINCT O.DROPDATE)>15 IN LAST 30 DAYS THEN 'FULL TIME' WHEN COUNT(DISTINCT O.DROPDATE)>=1 AND <=15 THEN 'PART TIME' IN LAST 30 DAYS ELSE NULL AS DAYSWORKED,
-- --CASE WHEN COUNT(DISTINCT O.DRV1NUM OF LEFT(DRIVERNUM,4 )>0 IN LAST 30 DAYS OF ORDERS>1 THEN 'MASTER IC' ELSE NULL AS MASTER
/* ABOVE TWO STATEMENT I WANT TO ADD */
FROM DRIVER D
FULL OUTER JOIN orde_ O ON O.DRV1ID=D.DRIVERID
AND ISNUMERIC(DRIVERNUM)=1 and DRIVERNUM NOT IN ('1010')
Expected Output That i want
DRVLICNUM Employee DOB COUNTRY ACTIVESTATUS
---------------------------------------------------------
055243324 CONTRACTOR 1985-04-13 ATLANTA FULL TIME
Here the ActiveStatus is Active because the driver worked more than 15 days in past 15 days or if it will less then 15 days it will be 'Part Time'
I don't have access to google drive link which you shared.
However, you will have to use CTE (common table expression) to get count of days and then use it compute value of ActiveStatus column.
Try using below code:
;
WITH CTE1
AS(
SELECT D.DRIVERID,
COUNT(DISTINCT O.DROPDATE) AS DayCount
FROM DRIVER AS D
LEFT JOIN ORDER AS O ON D.DRIVERID=O.DRV1ID AND O.DROPDATE BETWEEN CONVERT(DATE,DATEADD(DAY,-30,GETDATE())) AND GETDATE()
WHERE ISNUMERIC(D.DRIVERNUM)=1 AND D.DRIVERNUM NOT IN ('1010')
GROUP BY D.DRIVERID
)
SELECT DRVLICNUM,DOB,COUNTRY,CREDITLIMI,...
CASE
WHEN DayCount=0 THEN 'NOT ACTIVE'
WHEN DayCount<=15 THEN 'PART TIME'
WHEN DayCount>=30 THEN 'FULL TIME'
END AS ACTIVESTATUS
FROM CTE1 AS C
JOIN DRIVER AS D ON C.DRIVERID=D.DRIVERID
here is two siple queries for the first one:
1) select order by dates and group by driver (if there no more than one order per day):
select o.DRIVERID
, count(*) as cnt
from orde_ o
where o.DROPDATE betwen GETDATE() AND DATEADD(DAY,-30,GETDATE())
group by o.DRIVERID
2) select drivers and join groupped orders
select case
when o.ctn >= 15 then 'FULL TIME'
when o.ctn > 0 then 'PART TIME'
else 'NOT ACTIVE'
end
, <other fields you want>
from DRIVER as D
left join <query above> as o
on o.DRIVERID = d.DRIVERID
for the second one:
select left(d.DRIVERID, 4), count(*) as cnt
from DRIVER as D
group by left(d.DRIVERID, 4)
having count(*) > 1
and just join it, if is not null then compare whole id's

15 days before today in SQL Server

I am trying to find the list of specific job # from load date in our database with the specific condition and I have to use inner join as well.
i want to have last 15 days worth of Job # in my store procedure.
How do I set up the LoadDate that will change auto for last 15 days only.
Here is my query:
select pr.Job_Number,
Count(ItemCode1) as [Total Records],
si.PackageComplete
from
processed_record pr
inner join scanner_2 si on pr.ItemCode1 = si.ItemCode1
where
pr.Format_Name like '%Lin%' and pr.LoadDate >= '03/01/2016'
group by
pr.Job_Number, si.PackageComplete
order by
si.PackageComplete, pr.Job_Number
Your query should be as follow:
select pr.Job_Number,
Count(ItemCode1) as [Total Records],
si.PackageComplete
from
processed_record pr
inner join scanner_2 si on pr.ItemCode1 = si.ItemCode1
where
pr.Format_Name like '%Lin%' and pr.LoadDate >= DATEADD(DAY,-15,GETDATE())
group by
pr.Job_Number, si.PackageComplete
order by
si.PackageComplete, pr.Job_Number
GETDATE() will get the current date and DATEADD() function will add (subtract) -15 days.
You could use
CONVERT(date, DATEADD(DAY, -15, GETDATE()))
insted your fix Date Value.
With this code you recieve the current Date GetDate() and substract 15 Days DateAdd(day, -15, DateValue)
Finaly you Convert it into Date Typ Convert(date, value) otherwise you would get the current time, too.

Look at data in one date range and count from another date range

I'm stuck on a query where I am trying to get information on just customers that are newly acquired during a certain date range.
I had need to get a list of customers who placed their first order (of all time) in the first 6 months of the year. I then need to get total of their invoices, first invoice date, last invoice date, and count of orders for just the last 6 months.
I used a HAVING clause to ensure that I am just looking at customers that placed their first order in that 6 month period, but since we are past that period now, the total invoice info and order count information would include orders placed after this time. I considered including a restriction in the HAVING clause for the 'last invoice date', but then I am eliminating customers whose first order date was in the 6 month block, but also ordered after that. I'm not sure what to do next and am not having luck finding similar questions. Here is what I have so far:
SELECT c.customer, MAX(c.name) AS Name,
SUM(
CASE WHEN im.debit = 0
THEN im.amount * -1
ELSE im.amount
END
) AS TotalInvoiceAmount,
MIN(
im.date) AS FirstInvoiceDate,
MAX(
im.date) AS LastInvoiceDate,
COUNT(DISTINCT om.[order]) AS OrderCount
FROM invoicem im
INNER JOIN customer c ON im.customer = c.customer
FULL JOIN orderm om ON im.customer = om.customer
WHERE im.amount <> 0
GROUP BY c.customer
HAVING MIN(im.date) BETWEEN '01-01-2015' AND '06-30-2015'
ORDER BY c.customer
You can put the first 6 months qualification as a subquery. This would also work as a CTE
declare #startDate date = dateadd(month,-6,getdate())
SELECT c.customer, MAX(c.name) AS Name,
SUM(
CASE WHEN im.debit = 0
THEN im.amount * -1
ELSE im.amount
END
) AS TotalInvoiceAmount,
MIN(
im.date) AS FirstInvoiceDate,
MAX(
im.date) AS LastInvoiceDate,
COUNT(DISTINCT om.[order]) AS OrderCount
FROM invoice im
INNER JOIN (SELECT customer from invoice
GROUP BY customer
HAVING MIN(date) BETWEEN '01-01-2015'
AND '06-30-2015') im2
ON im.customer = im2.customer
INNER JOIN customer c ON im.customer = c.customer
FULL JOIN orderm om ON im.customer = om.customer
WHERE im.amount <> 0
AND im.date >= #startdate
GROUP BY c.customer
ORDER BY c.customer

datediff inside the time schedule

I need to calculate datedif(ss, start_time, end_time) between certain types of activities, which I pretty know how to do it. My code is:
WITH WorkDates AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY A.NUMBER ORDER BY datestamp DESC) AS RowNumber,
p2.affected_item as Service,
p1.close_time as close_time,
datestamp,
description,
a.type,
a.number as number
from ACTIVITYM1 a
left outer join probsummarym1 p1 on a.number = p1.number
inner join probsummarym2 p2 on p1.number = p2.number
where ((a.type like 'status%'
and (description like '%to Work In Progress%'
or description like '%from Work In Progress%')) or a.type like 'Closed')
)
SELECT
O1.Service,
O1.number,
O1.close_time,
sum(DATEDIFF(ss, O2.datestamp, O1.datestamp)) AS sum_of_time
FROM WorkDates O1
LEFT JOIN WorkDates O2
ON O2.RowNumber = O1.RowNumber + 1
and O2.number = O1.number
where O2.description like '%to Work In Progress%'
and (O1.description like '%from Work In Progress%' or O1.type like 'Closed')
group by O1.Service, O1.number, O1.close_time
order by O1.Service, O1.number
I'm doing it that way, because I need to calculate it between certain types of activities, and a number of such 'time windows' where it should be counted is not constant. And it works quite ok, but it calculates full time, including holidays, weekends
But there is one one more thing I need to have done here.
I would like to calculate datediff(ss, start_date, end_date) but only from Monday to Friday. It means, for example if start_date was on Friday at 16:00 and end_date on Monday at 7:00, datediff should be (24:00 - 16:00) + (07:00 - 00:00) = 15 hours. Is it possible?
You should calculate week difference, then convert it to seconds, then deduct it from datediff.
Like this:
sum(DATEDIFF(ss, O2.datestamp, O1.datestamp) - abs(DATEPART(ww,O2.datestamp) - DATEPART(ww,O1.datestamp)) * 2 * 24 * 60 * 60 ) AS sum_of_time

Resources