I have following table of Employee details
EmployeeName CompayId CompanyLastActive
---------------------------------------------------------
robort 112 10 Jun 2015 09:30
john 113 11 Jun 2015 11:10
sunny 114 14 Jun 2015 16:10
sumanth 114 15 Jun 2015 18:11
usha 115 07 Jun 2015 13:14
sudheer 115 14 Jun 2015 17:10
sweety 115 08 Jun 2015 16:34
I need to get the latest employee active time based on CompanyID with Comma separated EmployeeName like below
EmployeeName CompayId CompanyLastActive
---------------------------------------------------------
robort 112 10 Jun 2015 09:30
john 113 11 Jun 2015 11:10
sunny, sumanth 114 15 Jun 2015 18:11
usha, sudheer, sweety 115 14 Jun 2015 17:10
please help me how to solve.
SELECT EmployeeName = STUFF((
SELECT ',' + e1.EmployeeName
FROM dbo.Employee e1
WHERE e.CompayId = e1.CompayId
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
e.CompayId,
MAX(CompanyLastActive) as CompanyLastActive
FROM dbo.Employee e
GROUP BY e.CompayID
ORDER BY e.CompayId
Result:
EmployeeName CompayId CompanyLastActive
-------------------------------------------------------
robort 112 June, 10 2015 09:30:00
john 113 June, 11 2015 11:10:00
sunny,sumanth 114 June, 15 2015 18:11:00
usha,sudheer,sweety 115 June, 14 2015 17:10:00
Sample result in SQL Fiddle.
Check this out, i have not checked this as i'm feeling lazy to build schema, it would probably throw group by error, You can handle it
SELECT
Results.CompayId,
STUFF((
SELECT ', ' + CAST(EmployeeName AS VARCHAR(MAX))
FROM YourTable
WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
,max(Results.CompanyLastActive) as CompanyLastActive
FROM YourTable Results
GROUP BY CompayId
You can use this query:
SELECT EmployeeNames = dbo.EmployeeNamesPerCompany(CompanyID,', '),
CompanyID,
CompanyLastActive = MAX(CompanyLastActive)
FROM Employee e
GROUP BY CompanyID
ORDER BY MAX(CompanyLastActive)
If you have created a scalar valued function like this:
CREATE FUNCTION [dbo].[EmployeeNamesPerCompany]
(
#companyID Int,
#delimiter varchar(5)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #Names VARCHAR(8000)
SELECT #Names = COALESCE(#Names + #delimiter, '') + e.EmployeeName
FROM Employee e
WHERE e.CompanyId = #companyID
ORDER BY e.EmployeeName
return #Names
END
Sql-Fiddle Demo
Related
I have five tables:
Employees(EmpId, FirstName, LastName, DeptId,…)
Attendance(LogId, PunchIn, PunchOut,...)
Leave(RequestId, StartDate, endDate, LeaveType,...)
Holiday(HolidayId, Descriptions, StartDate, EndDate,....)
Business Travel(Request_Id, RequestDate, StartDate, EndDate,....)
I am trying to generate a monthly/Annual time-sheet report, time-sheet must represent an employee (or group of employees) status at the corresponding date like: on duty, later arrived, leave vacation, sick leave etc.
I create the following function
Create Function dbo.fn_GetEmployeeStatus(#LogDate Date, #BadgeNo int)
Returns char(3)
As
begin
Declare #status char(3) = null;
Declare #punchin DateTime;
Declare #punchout DateTime;
Declare #ShiftId tinyint;
Declare #LateEarly smallint;
Declare #id int = null;
Set #status = null;
Select #ShiftId = Shift_Id From Staff
Where Badge_No = Badge_No;
Select #id = Max(Holiday_Id) From Holiday
Where #LogDate Between StartDate And EndDate
if(#id is not null)
Set #status = 'HOL' --Holiday
else Set #status = null;
if(#status is null)
begin
Set #id = null;
Select #id = Max(Request_Id) From BusinessTravel
Where #LogDate Between Start_Date And End_Date
And Badge_No = #BadgeNo
if(#id is not null)
Set #status = 'BST' --Business Travel
else Set #status = null;
end
if(#status is null)
begin
Set #id = null;
Select #id = Max(LeaveCategory_Id) From Leaves
Where #LogDate Between Start_Date And End_Date
And Badge_No = #BadgeNo
if(#id is not null)
begin
Set #status = Case #id
When 1 Then 'ANV' --Annual Leave
When 2 Then 'SIC' --Sick leave
When 3 Then 'SLV' --Study leave
When 4 Then 'ELV' --Emergency leave
When 5 Then 'ULV' --Unpaid leave
When 6 Then 'HLV' --Haj Leave
When 7 Then 'MLV' --Marriage leave
When 8 Then 'DLV' --Death of a relative
When 9 Then 'PLV' --Paternity leave
When 7 Then 'MLV' --Materinty Leave
else 'UNK' end; --Unknown
end else Set #status = null;
end
if(#status is null)
begin
Select #punchin = Min(Log_Date), #punchout = Max(Log_Date) From AttendanceLog
Where Cast(Log_Date as Date) = #LogDate
And Badge_No = #BadgeNo
if(#punchin is not null)
begin
Select #LateEarly = dbo.fun_GetEarlyLateAmt(#punchin, 1, #ShiftId)
if(#LateEarly > 20)
begin
Select #LateEarly = dbo.fun_GetEarlyLateAmt(#punchout, 0, #ShiftId)
if(#LateEarly > 10)
Set #status = 'L&E'; --Late Arrive & Early left
else Set #status = 'LTE'; --Late Arrive
end else Set #status = 'ODU'; --On Duty
end --else Set #status = null;
end
if(#status is null)
begin
if ((DatePart(dw, #LogDate) + ##DateFirst) % 7) in(0, 6)
Set #status = 'WKE'; --Weekend
Set #status = 'ABS';
end --else Set #status = 'ABS';
Return #status;
end
--But the following failed
Declare
#BadgeNo int = 2523,
#Year int = 2019
;With data as (
Select DateName(month, InTime) Mon, LogInDay = DATEPART(DAY, DATEADD(HOUR, -6, InTime))
,LogYear = DATEPART(YEAR, InTime), LogMonth = DATEPART(MONTH, InTime),
dbo.fn_GetEmployeeStatus_2(InTime, Badge_No) eStatus From v_EmpAttendanceStatus--v_AttendanceLog
Where DATEPART(YEAR, InTime) = #Year
And Badge_No = #BadgeNo)
Select Mon, LogYear, LogMonth, IsNull([1], 0)[1], IsNull([2], 0)[2], IsNull([3], 0)[3], IsNull([4], 0)[4], IsNull([5], 0)[5], IsNull([6], 0)[6], IsNull([7], 0)[7], IsNull([8], 0)[8], IsNull([9], 0)[9], IsNull([10], 0)[10], IsNull([11], 0)[11], IsNull([12], 0)[12], IsNull([13], 0)[13], IsNull([14], 0)[14], IsNull([15], 0)[15], IsNull([16], 0)[16], IsNull([17], 0)[17], IsNull([18], 0)[18], IsNull([19], 0)[19], IsNull([20], 0)[20], IsNull([21], 0)[21], IsNull([22], 0)[22], IsNull([23], 0)[23], IsNull([24], 0)[24], IsNull([25], 0)[25], IsNull([26], 0)[26], IsNull([27], 0)[27], IsNull([28], 0)[28], IsNull([29], 0)[29], IsNull([30], 0)[30], IsNull([31], 0)[31]
From data
Pivot (
Max(eStatus)
For LogInDay In
([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31])
) as piv
Order By LogMonth
Above cte result not shown holidays and leave vacation. I need the report like bellow image.
--Sample Data
1- Employee Table:
#Badge_No FirstName LastName DeptId#
2523 Name1 Last1 1001
2524 Name2 Last2 1001
2525 Name3 Last3 1006
-------------------------------------------------------------------
2- Holiday Table:
ID Sescriprions StartDate EndDate
1 Holidy1 '02 Jun 2019' '08 Jun 2019'
1 Holidy2 '23 Sep 2019' '24 Sep 2019'
---------------------------------------------------------------------
3- Leave Table:
#Request_Id Badge_No StartDate EndDate LeaveCategory#
1 2525 '15 Dec 2018' '22 Jan 2019' 2 --Sick leave
...
101 2524 '01 Jan 209' '03 Jan 209' 2 --Sick Leave
2061 2523 '09 Jun 2019' '04 Jul 2019' 1 --Annual Leave
..
2125 2523 '22 Jul 2019' '22 Jul 2019' 5 --Unpaid leave
--------------------------------------------------------------
4- Attendance Table:
#Badge_No Punch-In Punch-Out Shift_Id#
2523 '01 Jan 2019 07:04' '01 Jan 2019 16:01' 1
2524 '01 Jan 2019 07:45 '01 Jan 2019 15:56' 1
.......
2523 '28 Jan 2019 06:50' '28 Jan 2019 16:03' 1
2524 '28 Jan 2019 07:02' '28 Jan 2019 16:00' 1
2525 '28 Jan 2019 07:42' '28 Jan 2019 16:00' 1
2523 '29 Jan 2019 07:30' '29 Jan 2019 15:59' 1
2524 '29 Jan 2019 06:58' '29 Jan 2019 16:01' 1
2523 '30 Jan 2019 07:13' '30 Jan 2019 07:18' 1
2525 '30 Jan 2019 09:18' '30 Jan 2019 07:18' 1
2524 '30 Jan 2019 08:11' '30 Jan 2019 16:00' 1
2525 '30 Jan 2019 10:26' '30 Jan 2019 16:00' 1
2523 '31 Jan 2019 11:27' '31 Jan 2019 15:54' 1
2524 '31 Jan 2019 07:02' '31 Jan 2019 15:51' 1
.......
2523 '25 Jul 2019 08:17' '25 Jul 2019 17:23' 1
--------------------------------------------------------------
5- BusinessTravel Table:
#Badge_No StartDate EndDate#
2523 '07 Jan 2019' '09 Jan 2019'
2525 '03 Mar 2019' '07 Mar 2019'
sql server group by week sum
I have below code, time table.
below are time table columns
below is user table columns
userid,firstname,lastname
below are records of time table
timeid,shiftdate,starttime,endtime,userid
1,1st Jun 2019,1:00,10:00,1
2,2st Jun 2019,1:00,10:00,2
3,3rd Jun 2019,4:00,11:00,1
10,11th Jun 2019,4:00,11:00,1
14,11th Jun 2019,4:00,11:00,1
19,11th Jun 2019,4:00,11:00,1
my question is I want to generate weekly total report
like below e.g.
Userid | 3rd June to 9th June | 10th to 16 June
1 10 20
2 5 5
I have tried below code
select sum(datediff(hour,startdate,enddate),userid,shiftdate from time
group by userid,shiftdate
my it is giving me total of daily with respect to user. but what i need
I ned to have sum of hours between first day of week to last day of each week.
my it is giving me total of daily with respect to user. but what i need
I ned to have sum of hours between first day of week to last day of each week.
can you help on it
This may help
DECLARE #TimeTable TABLE(
timeid INT,shiftdate DATETIME ,starttime TIME,endtime TIME ,userid INT
)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(1,'1 Jun 2019','1:00','10:00',1)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(2,'2 Jun 2019','1:00','10:00',2)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(2,'3 Jun 2019','1:00','10:00',2)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(3,'3 Jun 2019','4:00','11:00',1)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(10,'11 Jun 2019','4:00','11:00',1)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(14,'11 Jun 2019','4:00','11:00',3)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(19,'11 Jun 2019','4:00','11:00',3)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(2,'11 Jun 2019','1:00','10:00',2)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(10,'19 Jun 2019','4:00','11:00',1)
INSERT INTO #TimeTable(timeid,shiftdate,starttime,endtime,userid) VALUES(10,'20 Jun 2019','4:00','11:00',1)
;WITH WeeklyTotal
AS(
SELECT *
,DATEDIFF(HOUR,starttime,endtime) totalHours
,DATEPART(WEEK, shiftdate) - DATEPART(WEEK, DATEADD(MM, DATEDIFF(MM,0,shiftdate), 0))+ 1 AS weekOfMonth
FROM #TimeTable
)
SELECT * FROM (
SELECT userid,weekOfMonth,totalHours
FROM WeeklyTotal
) aaa
pivot
(
SUM(totalHours)
for weekOfMonth in ([1], [2], [3],[4],[5],[6])
) piv;
I try to get data year wise. I tried this query
select
year(SStartDate) as joinedyear ,
count(*) joined_total
from
Detail
where
client = 81
Group By
YEAR(StartDate)
union all
select
year(SEndDate) as leftyear,
count(*) left_total
from
Detail
where
client = 81
Group By
YEAR(SEndDate)
This shows correct data but this shows data like this
1900 12
2001 1
2012 3
2013 3
2016 45
1900 23
2002 34
2004 34
2015 1
2016 56
where as I want data like this
joinedyear joined_total leftyear left_total
1900 12 1900 45
2001 1 2002 34
2012 3 2004 34
2013 3 2015 1
2016 45 2016 56
Try This below query..it mat help you
select * from (
select year(SStartDate) as joinedyear ,
count(*) joined_total from Detail
where client=81
Group By YEAR(StartDate)
) as a
full outer join
(
select year(SEndDate) as leftyear , count(*) left_total from Detail
where client=81
Group By YEAR(SEndDate)
) as b
on a.joinedyear=b.leftyear
I have a table which contains data like this,
GroupName group_code company_name Company Jan Feb
USA G142 3M Corp 3MCorp 117 35
USA G23581 3M Corp 3MCorp 117 35
USA G899 3M Corp 3MCorp 117 35
USA G2165 MNA Inc. MNA Inc. 5 3
USA G6245 MNA Inc. MNA Inc. 5 3
USA G3425 Acterna Inc. Acterna Inc. 245 204
Final result should be 1 row per company name with maximum group_code value like this,
GroupName group_code company_name Company Jan Feb
USA G23581 3M Corp 3MCorp 117 35
USA G6245 MNA Inc. MNA Inc. 5 3
USA G3425 Acterna Inc. Acterna Inc. 245 204
How can I do that?
This should work for the test data you provided. It looks like you want to take the group_code that has the largest value (numerically) trailing the leading character. So, if I assume that correctly, you could try this:
WITH cteRankedGroupCodes
AS
(
select GroupName
, group_code
, company_name
, company
, jan
, feb
, rank() over ( partition by company_name
order by convert(int, substring(group_code, 2, len(group_code))) desc
) as GroupCodeRank
from SimilarRecords --your table
)
select GroupName
, group_code
, company
, jan
, feb
from cteRankedGroupCodes
where GroupCodeRank = 1
Use
SELECT [GroupName], max([group_code]), [company_name], [Company], [Jan], [Feb]
FROM Table1
GROUP BY [GroupName], [company_name], [Company], [Jan], [Feb]
If you need specifically to sort the group_code in numerical order, you will need to change the expression in the max function to introduce leading zeros or reformat the data to be lexicographically in sequence. See SqlFiddle for results.
You will need to use SQL Server Group By.
select GroupName , group_code , company_name , Company , Jan ,Feb
from table
group by GroupName , company_name ,Company , Jan , Feb
having group_code = max(group_code)
I have a query that works well but has one problem, it displays other data I don't want.
The data is the latest of each username.
Here is the query:
SELECT
l.USER_KEY AS id,
l.USER_ID AS username,
gl1.CHAR_KEY AS char_id,
gl1.NAME AS charname,
gl1.GATENUM AS server,
CONVERT(VARCHAR(20), l.LOGINTIME, 100) AS user_time,
CONVERT(VARCHAR(20), gl1.OCCUR_TIME, 100) AS char_time
FROM LOG_CONNECT201211 AS gl1
JOIN game.dbo.CHAR_INFOR AS g --character data
ON gl1.CHAR_KEY = g.CHAR0_KEY OR gl1.CHAR_KEY = g.CHAR1_KEY OR gl1.CHAR_KEY = g.CHAR2_KEY
JOIN login.dbo.USER_CHECK_LOGIN AS l --login data
ON g.USER_KEY = l.USER_KEY
JOIN (SELECT char_key, max(OCCUR_TIME) as mostrecent --game logs
FROM LOG_CONNECT201211
WHERE KIND=20 OR KIND=21
GROUP BY char_key) AS gl2
ON gl2.char_key = gl1.char_key and gl2.mostrecent = gl1.OCCUR_TIME
WHERE l.CHECKLOGIN = 1
ORDER BY username DESC
That returns:
id username char_id name map user_time char_time
------------------------------------------------------------------------------------
3667 zr5970 11002 warpath 4 Nov 15 2012 8:54AM Nov 7 2012 6:31AM
3667 zr5970 11004 bloodfines 4 Nov 15 2012 8:54AM Nov 7 2012 6:33AM
3667 zr5970 11003 hanzhou 1 Nov 15 2012 8:54AM Nov 15 2012 8:54AM
14999 yvacosta 52086 Creams 1 Nov 15 2012 8:17AM Nov 15 2012 8:17AM
23433 yurich 1911481 abal 5 Nov 15 2012 8:34AM Nov 9 2012 4:05PM
23433 yurich 1911482 yurich 5 Nov 15 2012 8:34AM Nov 15 2012 8:30AM
23433 yurich 1911483 sharmaine 5 Nov 15 2012 8:34AM Nov 15 2012 8:35AM
10967 yubiwamoi 33376 Dwina 1 Nov 15 2012 4:33AM Nov 15 2012 4:33AM
So the data is correct, but I only want to return one row per username.
On this data the username returns 3, with 3 names, but the only name I want is that one with the latest char_time.
Example correct data:
id username char_id name map user_time char_time
-----------------------------------------------------------------------------------
3667 zr5970 11003 hanzhou 1 Nov 15 2012 8:54AM Nov 15 2012 8:54AM
14999 yvacosta 52086 Creams 1 Nov 15 2012 8:17AM Nov 15 2012 8:17AM
23433 yurich 1911483 sharmaine 5 Nov 15 2012 8:34AM Nov 15 2012 8:35AM
10967 yubiwamoi 33376 Dwina 1 Nov 15 2012 4:33AM Nov 15 2012 4:33AM
Notice that I only displayed the data for zr5970 with the latest char_time
Please advice, Thank you.
Use ROW_NUMBER()
SELECT *
FROM
(
SELECT
l.USER_KEY AS id,
l.USER_ID AS username,
gl1.CHAR_KEY AS char_id,
gl1.NAME AS charname,
gl1.GATENUM AS server,
CONVERT(VARCHAR(20), l.LOGINTIME, 100) AS user_time,
CONVERT(VARCHAR(20), gl1.OCCUR_TIME, 100) AS char_time,
rn = row_number() over (partition by l.USER_KEY order by gl1.OCCUR_TIME DESC)
FROM LOG_CONNECT201211 AS gl1
JOIN game.dbo.CHAR_INFOR AS g --character data
ON gl1.CHAR_KEY = g.CHAR0_KEY OR gl1.CHAR_KEY = g.CHAR1_KEY OR gl1.CHAR_KEY = g.CHAR2_KEY
JOIN login.dbo.USER_CHECK_LOGIN AS l --login data
ON g.USER_KEY = l.USER_KEY
WHERE l.CHECKLOGIN = 1
) X
WHERE rn=1
ORDER BY username DESC
First select just the user name and the max time. This way you will have the correct number of rows. When you have that you can easily the other columns to your query...
select a.USER_KEY AS id,
l.USER_ID AS username,
gl1.CHAR_KEY AS char_id,
gl1.NAME AS charname,
gl1.GATENUM AS server,
CONVERT(VARCHAR(20), l.LOGINTIME, 100) AS user_time,
CONVERT(VARCHAR(20), gl1.OCCUR_TIME, 100) AS char_time
from
(select user_key, max(occur_time) as mostrecent
from log_connect2011
WHERE KIND=20 OR KIND=21
group by user_key) a
join LOG_CONNECT201211 AS gl1 on a.user_key = gl1.user_key and a.mostrecent = gl1.occur_time
JOIN game.dbo.CHAR_INFOR AS g --character data
ON gl1.CHAR_KEY = g.CHAR0_KEY OR gl1.CHAR_KEY = g.CHAR1_KEY OR gl1.CHAR_KEY = g.CHAR2_KEY
JOIN login.dbo.USER_CHECK_LOGIN AS l --login data
ON g.USER_KEY = l.USER_KEY
WHERE l.CHECKLOGIN = 1
ORDER BY username DESC