case when in sqlserver - sql-server

i try to use case in for my condition to show out which is late,but after i use case when my result show out too many result.
select
grp.checktime,
--min(CONVERT(smalldatetime,l.checktime)) as clockin,
--max(CONVERT(smalldatetime,l.checktime)) as clockout,
ClockIn = case when min(cast(l.checktime as time)) <= cast(sc.StartTime as time)
then convert(varchar(100), cast(l.checktime as time), 100)
else 'Late ClockIn ' + convert(varchar(100), cast(l.checktime as time), 100)
end,
Clockout = case when max(cast(l.checktime as time)) >= cast(sc.EndTime as time)
then convert(varchar(100), cast(l.checktime as time), 100)
else 'Early ClockOut ' + convert(varchar(100), cast(l.checktime as time), 100)
end,
l.userid,
u.showname,
u.BADGENUMBER
from checkinout l
inner join userinfo u on l.userid = u.userid
inner join UserUsedsclasses uuc on u.userid = uuc.userid
inner join SchClass sc on uuc.SchId = sc.schClassid
inner join (
select distinct CONVERT(Date,checktime) as checktime
from checkinout
group by CONVERT(Date,checktime)
) as grp on grp.checktime = CONVERT(Date, l.checktime)
where uuc.SchId = 1 and u.badgenumber = 107
and u.badgenumber not in (79, 103, 78)
and l.checktime >= dateadd(month, datediff(month, 0, GETDATE() ) , 0)
and l.checktime < dateadd(month, datediff(month, 0, GETDATE ())+1, 0)
group by grp.checktime,l.userid,u.showname,u.BADGENUMBER,sc.StartTime,l.checktime,sc.EndTime
my result show me

Change your group by to group by the date of l.checktime.
select
grp.checktime,
--min(convert(smalldatetime,l.checktime)) as clockin,
--max(convert(smalldatetime,l.checktime)) as clockout,
ClockIn = case when min(cast(l.checktime as time)) <= cast(sc.StartTime as time)
then convert(varchar(100), cast(l.checktime as time), 100)
else 'Late ClockIn ' + convert(varchar(100), cast(l.checktime as time), 100)
end,
Clockout = case when max(cast(l.checktime as time)) >= cast(sc.EndTime as time)
then convert(varchar(100), cast(l.checktime as time), 100)
else 'Early ClockOut ' + convert(varchar(100), cast(l.checktime as time), 100)
end,
l.userid,
u.showname,
u.BADGENUMBER
from checkinout l
inner join userinfo u on l.userid = u.userid
inner join UserUsedsclasses uuc on u.userid = uuc.userid
inner join SchClass sc on uuc.SchId = sc.schClassid
inner join (
select distinct convert(Date,checktime) as checktime
from checkinout
group by convert(Date,checktime)
) as grp on grp.checktime = convert(Date, l.checktime)
where uuc.SchId = 1 and u.badgenumber = 107
and u.badgenumber not in (79, 103, 78)
and l.checktime >= dateadd(month, datediff(month, 0, getdate() ) , 0)
and l.checktime < dateadd(month, datediff(month, 0, getdate ())+1, 0)
group by
grp.checktime
, l.userid
, u.showname
, u.BADGENUMBER
, sc.StartTime
, convert(date, l.checktime)
, sc.EndTime

Related

Too many Group By dilutes query results

I need some assistance on a SQL Query. I hope i titled it correctly as I do not want to mislead anyone.
I am attempting to generate a query which will eventually be placed into a view and be used in the Microsoft Power BI tool that will return a count for a given event in the EVENT field/column, which are:
6 – Out of Spec Above
7 – Out of Spec Below
…that occurred within a given time frame along with the total number of measurements tested.
I am successful if I only group by Date, Item Code, Plant Code, and Property using the query below.
SELECT
CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101) AS [Date],
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
dbo.OC_VDATA.UDL1 AS Plant_Code,
dbo.OC_VDATA.UDL5 as Property,
SUM(CASE WHEN OC_VDATA.EVENT = 6 THEN 1 WHEN OC_VDATA.EVENT = 7 THEN 1 ELSE 0 END) AS Out_of_Spec,
COUNT(*) AS Total_Measured
FROM
dbo.OC_VDATA INNER JOIN
dbo.OC_VDAT_AUX ON dbo.OC_VDATA.PARTNO = dbo.OC_VDAT_AUX.PARTNOAUX
AND dbo.OC_VDATA.DATETIME = dbo.OC_VDAT_AUX.DATETIMEAUX INNER JOIN
stagingPLM.dbo.ITEM_CODES ON LEFT(dbo.OC_VDATA.PARTNO, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
AND LEFT(dbo.OC_VDAT_AUX.PARTNOAUX, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
WHERE
CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101) = '08/21/2019'
and stagingPLM.dbo.ITEM_CODES.ITEM_CODE = '20SL'
AND dbo.OC_VDATA.UDL1 = '1011'
AND dbo.OC_VDATA.UDL5 = 'WEIGHT'
--(CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102) >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-13, 0))
GROUP BY
CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101),
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
dbo.OC_VDATA.UDL1,
dbo.OC_VDATA.UDL5
First Query Results:
If I add another grouping level, the EVENT, my Total_Measured column gets diluted. I expected this to happen.
SELECT
CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101) AS [Date],
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
dbo.OC_VDATA.UDL1 AS Plant_Code,
dbo.OC_VDATA.UDL5 as Property,
dbo.OC_VDATA.EVENT,
SUM(CASE WHEN OC_VDATA.EVENT = 6 THEN 1 WHEN OC_VDATA.EVENT = 7 THEN 1 ELSE 0 END) AS Out_of_Spec,
COUNT(*) AS Total_Measured
FROM
dbo.OC_VDATA INNER JOIN
dbo.OC_VDAT_AUX ON dbo.OC_VDATA.PARTNO = dbo.OC_VDAT_AUX.PARTNOAUX
AND dbo.OC_VDATA.DATETIME = dbo.OC_VDAT_AUX.DATETIMEAUX INNER JOIN
stagingPLM.dbo.ITEM_CODES ON LEFT(dbo.OC_VDATA.PARTNO, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
AND LEFT(dbo.OC_VDAT_AUX.PARTNOAUX, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
WHERE
CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101) = '08/21/2019'
and stagingPLM.dbo.ITEM_CODES.ITEM_CODE = '20SL'
AND dbo.OC_VDATA.UDL1 = '1011'
AND dbo.OC_VDATA.UDL5 = 'WEIGHT'
--(CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102) >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-13, 0))
GROUP BY
CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101),
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
dbo.OC_VDATA.UDL1,
dbo.OC_VDATA.UDL5,
dbo.OC_VDATA.EVENT
Second Query Results:
With all that said, what I really want is the results from the second query and merge in the Total_Measured column from the first query.
Results I want:
I thought using a CTE was the answer but that takes a while and eventually generates an error.
WITH CTE1 AS
(
SELECT
CONVERT(varchar, CONVERT(datetime, OC_VDAT_AUX.UDL40, 102), 101) AS Date,
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
OC_VDATA.UDL1 AS Plant_Code,
OC_VDATA.UDL5 AS Property,
--SUM(CASE WHEN OC_VDATA.EVENT = 6 THEN 1 WHEN OC_VDATA.EVENT = 7 THEN 1 ELSE 0 END) AS Out_of_Spec,
COUNT(OC_VDATA.EVENT) AS Total_Measured
FROM
OC_VDATA INNER JOIN
OC_VDAT_AUX ON OC_VDATA.PARTNO = OC_VDAT_AUX.PARTNOAUX
AND OC_VDATA.DATETIME = OC_VDAT_AUX.DATETIMEAUX INNER JOIN
stagingPLM.dbo.ITEM_CODES ON LEFT(OC_VDATA.PARTNO, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
AND LEFT(OC_VDAT_AUX.PARTNOAUX, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
WHERE
(CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102) >= DATEADD(month, - 13, GETDATE()))
GROUP BY
CONVERT(varchar, CONVERT(datetime, OC_VDAT_AUX.UDL40, 102), 101),
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
OC_VDATA.UDL1,
OC_VDATA.UDL5
),
CTE2 AS
(
SELECT
CONVERT(varchar, CONVERT(datetime, OC_VDAT_AUX.UDL40, 102), 101) AS Date,
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
OC_VDATA.UDL1 AS Plant_Code,
OC_VDATA.UDL5 AS Property,
OC_VDATA.EVENT,
COUNT(*) AS Out_of_Spec
FROM
OC_VDATA INNER JOIN
OC_VDAT_AUX ON OC_VDATA.PARTNO = OC_VDAT_AUX.PARTNOAUX
AND OC_VDATA.DATETIME = OC_VDAT_AUX.DATETIMEAUX INNER JOIN
stagingPLM.dbo.ITEM_CODES ON LEFT(OC_VDATA.PARTNO, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
AND LEFT(OC_VDAT_AUX.PARTNOAUX, 12) = stagingPLM.dbo.ITEM_CODES.SPEC_NO
WHERE
(CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102) >= DATEADD(month, - 13, GETDATE()))
GROUP BY
CONVERT(varchar, CONVERT(datetime, OC_VDAT_AUX.UDL40, 102), 101),
stagingPLM.dbo.ITEM_CODES.ITEM_CODE,
OC_VDATA.UDL1,
OC_VDATA.UDL5,
OC_VDATA.EVENT
)
SELECT
cte1.Date,
cte1.ITEM_CODE,
cte1.Plant_Code,
cte1.PROPERTY,
EVENT,
Out_of_Spec,
Total_Measured
FROM
cte1 INNER JOIN cte2 on cte1.Date = cte2.date
and cte1.ITEM_CODE = cte2.ITEM_CODE
and cte1.Plant_Code = CTE2.Plant_Code
and cte1.Property = cte2.Property
How to achieve what I want? Does anyone have any tips/tricks? Am I even on the right track? Frustration is starting to set in.
DECLARE #TargetDate varchar(10) = '08/21/2019'
;WITH PlainList AS
(
SELECT
[Date] = CONVERT(varchar, CONVERT(datetime, dbo.OC_VDAT_AUX.UDL40, 102), 101)
, Item_Code = stagingPLM.dbo.ITEM_CODES.ITEM_CODE
, Plant_Code = dbo.OC_VDATA.UDL1
, Property = dbo.OC_VDATA.UDL5
, [Event] = dbo.OC_VDATA.[EVENT]
, Out_of_Spec = CASE OC_VDATA.[EVENT]
WHEN 6 THEN 1
WHEN 7 THEN 1
ELSE 0
END
FROM dbo.OC_VDATA
INNER JOIN dbo.OC_VDAT_AUX ON dbo.OC_VDAT_AUX.PARTNOAUX = dbo.OC_VDATA.PARTNO
AND dbo.OC_VDAT_AUX.DATETIMEAUX = dbo.OC_VDATA.[DATETIME]
INNER JOIN stagingPLM.dbo.ITEM_CODES ON stagingPLM.dbo.ITEM_CODES.SPEC_NO = LEFT(dbo.OC_VDATA.PARTNO , 12)
AND stagingPLM.dbo.ITEM_CODES.SPEC_NO = LEFT(dbo.OC_VDAT_AUX.PARTNOAUX , 12)
WHERE 1=1
AND stagingPLM.dbo.ITEM_CODES.ITEM_CODE = '20SL'
AND dbo.OC_VDATA.UDL1 = '1011'
AND dbo.OC_VDATA.UDL5 = 'WEIGHT'
)
SELECT
[Date]
, Item_Code
, Plant_Code
, Property
, [Event]
, Out_of_Spec = SUM(Out_of_Spec)
, Total_Measured = SUM(1)
FROM PlainList P
GROUP BY
[Date]
, Item_Code
, Plant_Code
, Property
, [Event]
HAVING [Date] = #TargetDate

Getting the result with date from yesterday

I am trying to tally all Invoices without Sales Order and show it as an SQL query. The date should be the Invoices entered yesterday. The challenge is it seems that the result is static and won't change
SELECT TOP (100) PERCENT CONVERT(varchar, DATEADD(dd, - 1, GETDATE()), 103) AS Date,
'Invoices w/o SO' AS Type,
COUNT(dbo.Invoice.InvoiceID) AS Orders,
COUNT(dbo.Invoice.InvoiceID) AS Chairs,
ISNULL(ROUND(SUM(dbo.InvoiceDetails.ExtendedPrice), 2), 0) AS [Total Ex GST]
FROM dbo.Invoice INNER JOIN dbo.Customers
ON dbo.Invoice.CustomerID = dbo.Customers.CustomerID
INNER JOIN dbo.InvoiceDetails
ON dbo.Invoice.InvoiceID = dbo.InvoiceDetails.InvoiceID
WHERE (dbo.InvoiceDetails.ItemNo = 'TRIAL CHAIR')
OR
(dbo.InvoiceDetails.ItemNo = 'STORAGE')
OR
(dbo.InvoiceDetails.ItemNo = 'RSTF01')
OR
(dbo.InvoiceDetails.ItemNo = 'FRDMC01')
AND
(dbo.Invoice.CredInvoiceNo IS NULL)
AND
(dbo.Invoice.EntryDate >= CONVERT(char(8), DATEADD(dd, - 1, GETDATE()), 112))
AND
(dbo.Customers.CustomerID <> 187)
Screenshot
Thanks everyone.
I changed the query and it worked!
SELECT
CONVERT(varchar, DATEADD(dd, -1, GETDATE()), 103) AS Date,
'Invoices w/o SO' AS Type,
COUNT(dbo.Invoice.InvoiceID) AS Orders,
COUNT(dbo.Invoice.InvoiceID) AS Chairs,
ISNULL(ROUND(SUM(dbo.InvoiceDetails.ExtendedPrice), 2), 0) AS [Total Ex GST]
FROM dbo.Invoice
INNER JOIN dbo.Customers
ON dbo.Invoice.CustomerID = dbo.Customers.CustomerID
INNER JOIN dbo.InvoiceDetails
ON dbo.Invoice.InvoiceID = dbo.InvoiceDetails.InvoiceID
WHERE (dbo.InvoiceDetails.ItemNo IN ('TRIAL CHAIR', 'STORAGE', 'RSTF01', 'FRDMC01'))
AND (dbo.Invoice.CredInvoiceNo IS NULL)
AND (dbo.Customers.CustomerID <> 187)
AND (DATEDIFF(DAY, dbo.Invoice.EntryDate, GETDATE()) = 1)

Query Very Slow to Run, might need optimisation?

I have below code and it took around 10 minutes to run. I could not figure out why though... Any suggestion? Looking up for a month worth of sales which around 51000 lines of transaction.
WITH CUSTOMER_SALESTYPE AS (
SELECT CUSTOMER_ID
,CUSTOMER_NAME
,CASE Sales_type WHEN 'A' THEN 'TRADE'
WHEN 'B' THEN 'WHOLESALE'
WHEN 'C' THEN 'TRADE'
WHEN 'M' THEN 'WHOLESALE'
WHEN 'N' THEN 'WHOLESALE'
WHEN 'P' THEN 'TRADE'
WHEN 'S' THEN 'TRADE'
WHEN 'V' THEN 'WHOLESALE' END AS 'SALESTYPE'
,CASE B.STATE WHEN 'TAS' THEN 'VIC' ELSE B.STATE END AS 'STATE'
FROM BSIT_ERA_RAW_DATA.DBO.CUSTOMER A
LEFT JOIN BSIT_ERA_RAW_DATA.DBO.TERRITORY_REP B ON A.TERR_CODE = B.TERR_CODE
WHERE BSIT_STORE = 'STORE01'
AND B.STATE IN ('VIC','QLD','NSW','WA','SA','TAS')
)
SELECT B.STATE
,B.SALESTYPE
,C.BRAND_NAME
,SUM(TOTAL_SALE_AMT) AS 'Net Sales'
,SUM(TOTAL_COST) AS 'Net Cost'
,SUM(TOTAL_SALE_AMT) - SUM(TOTAL_COST) AS 'Net Margin'
,STR(100*((SUM(TOTAL_SALE_AMT) - SUM(TOTAL_COST)) / SUM(TOTAL_SALE_AMT)),5,2) + '%' AS 'Net Margin%'
FROM [BSIT_ERA_RAW_DATA].[dbo].[PROD_HIST] A
INNER JOIN CUSTOMER_SALESTYPE B ON A.CUST_NO = B.CUSTOMER_ID
INNER JOIN BSIT_ERA_RAW_DATA.dbo.DIM_PART C ON RIGHT(A.PART_NO,LEN(A.PART_NO)-2) = C.PART_NO
WHERE TRANS_DATE >= DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0)
AND TRANS_DATE < DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) , 0)
AND TRANS_TYPE IN ('SLS', 'CM')
AND INVOICE_NO IS NOT NULL
AND A.TRANS_CODE != 'L'
AND A.TRANS_CODE != 'PL'
OR
TRANS_DATE >= DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0)
AND TRANS_DATE < DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) , 0)
AND TRANS_TYPE IN ('SLS', 'CM')
AND INVOICE_NO IS NOT NULL
AND A.TRANS_CODE IS NULL
GROUP BY B.STATE
,B.SALESTYPE
,C.BRAND_NAME

How to sum count in SQL Server?

When i used this to count how many employees working in each departments , its working fine :
-- Count
totals.Nr_Employees as TotalEmployees
LEFT JOIN
(select p1.DepartmentName, count(distinct u.Id) Nr_Employees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
) totals on totals.DepartmentName = p.DepartmentName
BUT, when i want to make total of count or sum count , i do something like this ,but its not working and i dont know its right way to do or not ! Can someone please point me in the right direction?
-- SUM
SummerCount.TotalEmployees as sumEmployees
LEFT JOIN
(select p1.DepartmentName, sum(count(distinct u.Id)) TotalEmployees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
) SummerCount on SummerCount.DepartmentName = p.DepartmentName
AND , put Querys together:
-- Count & SUM
totals.Nr_Employees as TotalEmployees,
SummerCount.TotalEmployees as sumEmployees
FROM
LEFT JOIN
(select p1.DepartmentName, count(distinct u.Id) Nr_Employees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
) totals on totals.DepartmentName = p.DepartmentName
LEFT JOIN
(select p1.DepartmentName, sum(count(distinct u.Id)) TotalEmployees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
) SummerCount on SummerCount.DepartmentName = p.DepartmentName
Screenshots (wrong sum):
Aggregate functions as operators of aggregate functions are not supported. This is, why your statment doe not work.
You can either use the WITH ROLLUP clause or put your statement into a subselect and build the sums in the outer statement.
Use a common table expression to get replace the first query, and select sum from that cte to replace the second one:
;WITH EmployeesCount AS
(
select p1.DepartmentName, count(distinct u.Id) Nr_Employees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
)
And then, in your main query:
...
LEFT JOIN
EmployeesCount As totals on totals.DepartmentName = p.DepartmentName
LEFT JOIN
(
SELECT SUM(Nr_Employees)
FROM EmployeesCount
) As SummerCount on SummerCount.DepartmentName = p.DepartmentName
Update
;WITH EmployeesCount AS
(
select p1.DepartmentName, count(distinct u.Id) Nr_Employees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
)
SELECT totals.Nr_Employees as TotalEmployees,
SummerCount.Nr_Employees as sumEmployees
FROM
dbo.Paychecks AS p INNER JOIN dbo.Users AS u ON u.Id=p.UserId
INNER JOIN dbo.EmploymentStatuses AS E ON E.Id = u.EmploymentStatusId
LEFT OUTER JOIN dbo.EmployeeTerminationQueue AS etq on etq.UserId = u.Id
LEFT OUTER JOIN dbo.TerminationReasons AS t on t.Id = etq.TerminationReasonid
LEFT JOIN EmployeesCount As totals on totals.DepartmentName = p.DepartmentName
CROSS JOIN
(
SELECT SUM(Nr_Employees) As Nr_Employees
FROM EmployeesCount
) As SummerCount
Full query
;WITH EmployeesCount AS
(
select p1.DepartmentName, count(distinct u.Id) Nr_Employees
from Paychecks p1
join Users u on u.Id = p1.UserId
where u.customerid=214 and u.isdeleted=0
group by p1.DepartmentName
)
SELECT DISTINCT u.Id, u.FirstName + ' ' + u.LastName AS Medarbajder,
u.SSN AS CPRNR,
(CASE
WHEN u.SSN IS NOT NULL THEN
DATEDIFF(YEAR,CONVERT(date,STUFF(LEFT(u.SSN, 4), 3, 0, '.') + '.' + CAST(DATEPART(YEAR, GETDATE()) / 100 - 1 as char(2)) + SUBSTRING(u.SSN, 5, 2), 104) , GETDATE())
ELSE
NULL
END) As Aldre ,
(CASE WHEN right(rtrim(SSN), 1) IN ('1', '3', '5', '7', '9') THEN 'M'
WHEN right(rtrim(SSN), 1) IN ('2', '4', '6', '8', '0') THEN 'K'
END) as Køn,
convert(varchar(10), p.WorkStartDate, 105) AS StartDato ,
(CASE
WHEN u.ResignationDate IS NOT NULL THEN
CONVERT(varchar(4), DATEDIFF(dd, WorkStartDate, u.ResignationDate)/365) + ' år '+
CONVERT(varchar(4), DATEDIFF(MONTH, WorkStartDate, u.ResignationDate) % 12) + ' måneder '+
CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, WorkStartDate, u.ResignationDate), WorkStartDate), u.ResignationDate),
DATEADD(yy, DATEDIFF(yy, WorkStartDate, u.ResignationDate), WorkStartDate)), u.ResignationDate) AS varchar(2)) +' dag '
ELSE
CONVERT(varchar(4), DATEDIFF(dd, WorkStartDate, GETDATE())/365) + ' år '+
CONVERT(varchar(4), DATEDIFF(MONTH, WorkStartDate, GETDATE()) % 12) + ' måneder '+
CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, WorkStartDate, GETDATE()), WorkStartDate), GETDATE()),
DATEADD(yy, DATEDIFF(yy, WorkStartDate, GETDATE()), WorkStartDate)), GETDATE()) AS varchar(2)) +' dag ' end) as Ancinitet,
(CASE
WHEN u.ResignationDate IS NOT NULL THEN
DATEDIFF(day, WorkStartDate, u.ResignationDate)
ELSE
DATEDIFF(day, WorkStartDate, GETDATE())
end) as AncinitetAntalDag,
p.DepartmentName AS Afdelinger,
E.Name AS Ansættelsesstatus,
u.ResignationDate AS Opsigelsesdato,
(CASE WHEN etq.Id IS NOT NULL THEN t.Name ELSE 'Aktiv' END) AS Terminationreason,
totals.Nr_Employees as TotalEmployees,
SummerCount.Nr_Employees as sumEmployees
FROM
dbo.Paychecks AS p INNER JOIN dbo.Users AS u ON u.Id=p.UserId
INNER JOIN dbo.EmploymentStatuses AS E ON E.Id = u.EmploymentStatusId
LEFT OUTER JOIN dbo.EmployeeTerminationQueue AS etq on etq.UserId = u.Id
LEFT OUTER JOIN dbo.TerminationReasons AS t on t.Id = etq.TerminationReasonid
LEFT JOIN EmployeesCount As totals on totals.DepartmentName = p.DepartmentName
CROSS JOIN
(
SELECT SUM(Nr_Employees) As Nr_Employees
FROM EmployeesCount
) As SummerCount
WHERE u.CustomerId=214 AND u.IsDeleted = 0
AND etq.StartDate >= #EndDateFrom AND etq.StartDate <= #EndDateTo
AND
((#Gender != 'B' AND
#Gender = (CASE WHEN right(rtrim(SSN), 1) IN ('1', '3', '5', '7', '9') THEN 'M'
WHEN right(rtrim(SSN), 1) IN ('2', '4', '6', '8', '0') THEN 'K'
END))
OR
(#Gender = 'B'))
AND
((#TerminationReason != 0 AND #TerminationReason = (CASE WHEN etq.Id IS NOT NULL THEN t.Id ELSE 0 END))
OR
(#TerminationReason = 0))
AND u.EmploymentStatusId = 2
order by p.DepartmentName

Convert date time in SQL

I would like to find out which user are late clock in example clock in time on 9:00Am more than 9:00am declare as late but my result show me more than 10:00Am just count as late
DECLARE #clockin as varchar
DECLARE #clockout as varchar
DECLARE #reportdate as datetime
--SET #clockin = CONVERT(108,'08:30')
SET #clockin = CONVERT(varchar(10),CAST('9:00' AS TIME),100)
SET #clockout = CONVERT(varchar(10),CAST('18:30' AS TIME),100)
SET #reportdate = month(GETDATE())
SELECT
u.showname AS showname,
l.USERID AS USERID,
u.BADGENUMBER AS BADGENUMBER,
l.CHECKTIME AS CHECKTIME,
CASE
WHEN DATEPART(HOUR, l.CHECKTIME) <= #clockin
THEN CONVERT(varchar(10), CAST(l.CHECKTIME AS TIME), 100)
ELSE 'late ' + CONVERT(varchar(100), CAST(l.CHECKTIME AS TIME), 100)
END AS Time
FROM
CHECKINOUT l
INNER JOIN
USERINFO u ON l.USERID = u.USERID
WHERE
u.showname IS NOT NULL
AND u.BADGENUMBER > 100
AND CHECKTIME >= '1 jan 2017'
AND CHECKTIME <= '31 jan 2017'
--GROUP BY l.USERID, u.showname, u.BADGENUMBER
ORDER BY
u.BADGENUMBER
Result
To compare with time not just 'hour'!
DECLARE #clockin as TIME
DECLARE #clockout as TIME
DECLARE #reportdate as datetime
SET #clockin = CAST('9:00' AS TIME)
SET #clockout = CAST('18:30' AS TIME)
SET #reportdate = month(GETDATE())
SELECT
u.showname, l.USERID, u.BADGENUMBER, l.CHECKTIME,
CASE
WHEN CAST(l.CHECKTIME AS TIME) < = #clockin
THEN CONVERT(VARCHAR(10), CAST(l.CHECKTIME AS TIME), 100)
ELSE 'late ' + CONVERT(VARCHAR(100), CAST(l.CHECKTIME AS TIME), 100)
END AS Time
FROM
CHECKINOUT l
INNER JOIN
USERINFO u ON l.USERID = u.USERID
WHERE
u.showname IS NOT NULL
AND u.BADGENUMBER > 100
AND CHECKTIME >= '1 jan 2017'
AND CHECKTIME <= '31 jan 2017'
ORDER BY
u.BADGENUMBER
All you have to do is remove the equal sign. The person arrived at nine so they are not late because that equals the start time. You can also subract 59 seconds to the check in time so 9:00:30 am doesn't show as late.
I would recommend using a separate field for late flag so people can use this data in other reports more easily in excel or whatever: if the person is late how much are they late by stuff like that
Select
u.showname, l.USERID, u.BADGENUMBER, l.CHECKTIME,
case
when datepart(HOUR,l.CHECKTIME) < #clockin

Resources