Magic!
;with Employees (EmployeeId, HireDate, DepartmentId) as
(
select 1, getdate()-10, 1 union
select 2, getdate()-10, 1 union
select 3, getdate()-8, 2 union
select 4, getdate()-7, 3 union
select 5, getdate()-6, 1
)
select cast(datepart(year, HireDate) as varchar(4)) +
right(replicate('0' ,4)+cast(DepartmentId as varchar(4)), 4) +
right(replicate('0' ,4)+cast(row_number() over (partition by DepartmentId,datepart(year, HireDate) order by HireDate asc) as varchar(4)), 4) EmployeeCode
,DepartmentId
,EmployeeId
,convert(varchar(10), HireDate, 120) HireDate
from Employees
Will give us the following:
EmployeeCode DepartmentId EmployeeId HireDate
------------ ------------ ----------- ----------
201000010001 1 1 2010-09-05
201000010002 1 2 2010-09-05
201000010003 1 5 2010-09-09
201000020001 2 3 2010-09-07
201000030001 3 4 2010-09-08
UPDATE:
Now supposing you want to add a new employee to the Department #2 today. Here's how I'd calculate a new EmployeeCode for this employee:
declare @DepartmentId int
set @DepartmentId = 2
select
cast(datepart(year, getdate()) as varchar(4)) +
right(replicate('0' ,4)+cast(@DepartmentId as varchar(4)), 4) +
right(replicate('0' ,4)+cast(isnull(max(cast(right(EmployeeCode,4) as smallint)),0) + 1 as varchar(4)), 4) EmployeeCode
from dbo.Employees as e
where DepartmentId = @DepartmentId
and datepart(year, hiredate) = datepart(year, getdate())
UPDATE:
As you can see, if you add an employee to a hitherto nonexistent department, say, #200, then the max clause would return null as there are no employees in this department and it'd get isnulled to 0 + 1, so you'd get a perfectly normal 201002000001
for that employee.
Suppose a year passed and now it's 2011 and this last filtering clause again would null the max clause and the procedure would repeat and we'd get 201102000001
for a new employee in that new department this next-year.