Reputation: 355
I have a query below:
SELECT
CASE a.SkedName WHEN 'Restday' THEN 1 WHEN 'No Schedule' THEN 2 ELSE 3 END AS TS,
DateAdd(Year,2,TDate) TDate,
CASE a.SkedName WHEN 'Restday' THEN '00:00:00' WHEN 'No Schedule' THEN '00:00:00' ELSE SchedTI END AS SchedTimeIn,
DateAdd(Year,2,TDate) AS DateTimeIn,
DateAdd(Year,2,TDate) AS DateTimeOut,
left(emp_firstname,1) + '. ' + left(emp_middlename,1) + '. ' + emp_lastname empName,
SkedName
FROM EmpList a
INNER JOIN tbl_employee b ON a.EmpId = b.emp_id
ORDER BY SchedTimeIn, a.SkedName, emp_lastname, emp_firstname
It returns this result:
TS TDate SchedTimeIn DateTimeIn DateTimeOut empName SkedName
2 2017-04-01 00:00:00 2017-04-01 2017-04-01 L. C. Manalo No Schedule
2 2017-04-02 00:00:00 2017-04-02 2017-04-02 L. C. Manalo No Schedule
2 2017-04-03 00:00:00 2017-04-03 2017-04-03 L. C. Manalo No Schedule
2 2017-04-04 00:00:00 2017-04-04 2017-04-04 L. C. Manalo No Schedule
1 2017-04-04 00:00:00 2017-04-04 2017-04-04 J. S. Bio Restday
1 2017-04-05 00:00:00 2017-04-05 2017-04-05 J. S. Bio Restday
3 2017-04-27 09:00:00 2017-04-27 2017-04-27 R. M. Jakosalem 9:00-6:00 Semi-Flexi
3 2017-04-28 09:00:00 2017-04-28 2017-04-28 R. M. Jakosalem 9:00-6:00 Semi-Flexi
3 2017-04-29 09:00:00 2017-04-29 2017-04-29 R. M. Jakosalem 9:00-6:00 Semi-Flexi
However, my desired result is to remove the redundancy of "No Schedule" and "Restday" Schedule Type.
Instead of this:
TS TDate SchedTimeIn DateTimeIn DateTimeOut empName SkedName
2 2017-04-01 00:00:00 2017-04-01 2017-04-01 L. C. Manalo No Schedule
2 2017-04-02 00:00:00 2017-04-02 2017-04-02 L. C. Manalo No Schedule
2 2017-04-03 00:00:00 2017-04-03 2017-04-03 L. C. Manalo No Schedule
2 2017-04-04 00:00:00 2017-04-04 2017-04-04 L. C. Manalo No Schedule
1 2017-04-04 00:00:00 2017-04-04 2017-04-04 J. S. Bio Restday
1 2017-04-05 00:00:00 2017-04-05 2017-04-05 J. S. Bio Restday
My desired result is setting TDate to MAX date of SkedName, DateTimeIn as MinDate, DateTimeOut as MaxDate of "No Schedule" and "Restday" per employee to avoid too many rows:
TS TDate SchedTimeIn DateTimeIn DateTimeOut empName SkedName
2 2017-04-04 00:00:00 2017-04-01 2017-04-04 L. C. Manalo No Schedule
1 2017-04-05 00:00:00 2017-04-04 2017-04-05 J. S. Bio Restday
I tried "GROUP BY SkedName HAVING SkedName = 'No Schedule' AND SkedName = 'Restday'". But it gives me an error
Column 'EmpList.TDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I don't know what to do. I appreciate any answers and suggestions. Badly need help :( Thanks a lot.
Upvotes: 1
Views: 595
Reputation: 194
You can achieve it by using cte and dense_rank() as below
;With cte as
(
SELECT
CASE a.SkedName WHEN 'Restday' THEN 1 WHEN 'No Schedule' THEN 2 ELSE 3 END AS TS,
DateAdd(Year,2,TDate) TDate,
CASE a.SkedName WHEN 'Restday' THEN '00:00:00' WHEN 'No Schedule' THEN '00:00:00' ELSE SchedTI END AS SchedTimeIn,
DateAdd(Year,2,TDate) AS DateTimeIn,
DateAdd(Year,2,TDate) AS DateTimeOut,
left(emp_firstname,1) + '. ' + left(emp_middlename,1) + '. ' + emp_lastname empName,
SkedName,
dense_rank() over (partition by a.EmpId,SkedName order by DateAdd(Year,2,TDate)) as rn,
a.EmpId as empid
FROM EmpList a
INNER JOIN tbl_employee b ON a.EmpId = b.emp_id
)
Select TS,TDate,SchedTimeIn,DateTimeIn,
case when skedname in ('No Schedule','Restday')
then
(Select top 1 DateTimeOut from cte where rn = (select max(rn) from cte cin where cin.empid=cout.empid and cin.skedName = cout.skedName) and empid=cout.empid and skedName=cout.skedName)
else
DateTimeOut end as DateTimeOut,
empName,SkedName
from cte cout where rn=1 or skedName not in ('No Schedule','Restday')
ORDER BY SchedTimeIn, SkedName, emp_lastname, emp_firstname
Upvotes: 1
Reputation: 709
Based on my understanding,
I have edited my answer now.
;WITH cte
AS (SELECT ts,
tdate,
schedtimein,
datetimein,
datetimeout,
empname,
skedname,
Row_number()
OVER(
partition BY skedname
ORDER BY datetimein) AS Rn_in,
Row_number()
OVER(
partition BY skedname
ORDER BY datetimeout DESC) AS Rn_out
FROM (SELECT CASE a.skedname
WHEN 'Restday' THEN 1
WHEN 'No Schedule' THEN 2
ELSE 3
END AS TS,
Dateadd(year, 2, tdate) TDate,
CASE a.skedname
WHEN 'Restday' THEN '00:00:00'
WHEN 'No Schedule' THEN '00:00:00'
ELSE schedti
END AS SchedTimeIn,
Dateadd(year, 2, tdate) AS DateTimeIn,
Dateadd(year, 2, tdate) AS DateTimeOut,
LEFT(emp_firstname, 1) + '. '
+ LEFT(emp_middlename, 1) + '. ' + emp_lastname empName,
skedname
FROM emplist a
INNER JOIN tbl_employee b
ON a.empid = b.emp_id)A),
cte1
AS (SELECT a.ts,
b.tdate,
a.schedtimein,
a.datetimein,
b.datetimeout,
a.empname,
a.skedname,
a.rn_in,
b.rn_out
FROM cte a
JOIN cte b
ON a.ts = b.ts
AND a.rn_in = b.rn_out
WHERE a.skedname IN ( 'No Schedule', 'Restday' )) SELECT ts,
tdate,
schedtimein,
datetimein,
datetimeout,
empname,
skedname
FROM cte1
WHERE rn_in = 1
UNION
SELECT ts,
tdate,
schedtimein,
datetimein,
datetimeout,
empname,
skedname
FROM cte
WHERE skedname NOT IN ( 'No Schedule', 'Restday' )
Note: I have used Row_number function.
Upvotes: 1
Reputation: 265
try:
select Min(DateTimeIn),Max(DateTimeOut),empname,SkedName from Emplist group by empname,SkedName
Upvotes: 1