Showing posts with label employees. Show all posts
Showing posts with label employees. Show all posts

Friday, March 23, 2012

Listing results based on the starting alphabet

Hi,

I have a report which lists out the employees' details. I need A-Z links above the report, On clicking on an alphabet, say "C", should display all the employee details whose name starts with the selected alphabet. In the stored procedure we can accept the character and return back those results. But it is not a drill report and we need the result in the same report. Is there any way so that on clicking each link, the output will be shown in the same report. Any help is appreciated.

Thanks in advance,

Sonu

There are 2 ways to do this:

1. Create 26 datasets with the same SQL query but different filter criteria. For example, the first dataset will have the filter criteria as Fields!Name.Value LIKE 'A%', second will have Fields!Name.Value LIKE 'B%' and so on... This has to be set in the Filters tab of each dataset. Then have 26 tables in your report, each linked to the corresponding datasets. So, now when you click on A at the top of the report, have the Action set to Jump to bookmark and the value of bookmark will be the name of the corresponding table.

2. Create just 1 report with all the alphabets link at the top. Then create a report which will accept an alphabet as input parameter and display the results based on it. Set the action of the alphabets to Jump to report and set the parameters to be sent, which will the textbox value itself.

Shyam

|||

Hi Shyam,

Thanks a lot for your quick reponse. I followed the 2nd approach you have mentioned. Created only one report with alphabets link at the top. On clicking on to the link, the action of 'Jump to Report' is set as the same report along with the parameter.

Thanks again,

Sonu.

|||

Can you please mark my post as answer?

Shyam

Monday, March 19, 2012

List up-coming birthdays

I've got an employee table with a date of birth field in it. i need a query that will a allow me to list all employees who's birthdays are coming up the next 30 days (or 1 month, if easier). I've tried several approaches & am getting nowhere... Any help would be greatly appreciated.

Regards,
Jacques Matthee.SELECT *
FROM Employes
WHERE DATEDIFF(day, birthday, getdate())<=30|||oups !

that needs a little reajustment
on moment please...|||Thanks for the quick reply! i'll give it a bash!

Originally posted by Karolyn
SELECT *
FROM Employes
WHERE DATEDIFF(day, birthday, getdate())<=30|||now it returns everything, because the birthdays are in the 1970s & 80s compared to the current year which is 2004.

Originally posted by jacmat
Thanks for the quick reply! i'll give it a bash!|||it doesn't work
I'm creating a function for you
that you'll able to use the get the good results|||just a few minutes ...|||select id
, name
, dob
from employees
where datediff(dd
, getdate()
, cast(convert(char(4),year(getdate()) & '/'
& convert(char(5),dob,101)
as datetime)
) <= 30|||create this function

CREATE function dbo.DatePart(@.Date Varchar(26), @.Format VarChar(20))
returns Varchar(10) as
begin

return( (case @.Format
when 'YYYY' then Convert(char(4), Year(@.Date))
when 'MM' then Replicate('0', Len(Cast(Month(@.Date) as char(2)))) + Cast(Month(@.Date) as char(2))
when 'DD' then Replicate('0', Len(Cast(Day(@.Date) as char(2)))) + Cast(Day(@.Date) as char(2))
end))
end|||SELECT * FROM Employes
Where
DateDiff(day,
Cast(
RTrim(dbo.DatePart(getdate(), 'YYYY')) + '-' +
RTrim(dbo.DatePart('2002-01-02','DD')) + '-' +
RTrim(dbo.DatePart('2002-01-02','MM')) as datetime),getdate())<=30|||r937 solution's is quite is simpler...|||I always forget the convert format number (like 101)

very practical...
I'll remember this|||Karolyn, you have to put getdate() as the 2nd parameter in DATEDIFF because you want birthdays 30 days after today, not 30 days before|||a soooooo little detail

or put -30|||hey, R937 can you answer my concat null option question ?
(posted recently)|||Originally posted by jacmat
I've got an employee table with a date of birth field in it. i need a query that will a allow me to list all employees who's birthdays are coming up the next 30 days (or 1 month, if easier). I've tried several approaches & am getting nowhere... Any help would be greatly appreciated.

Regards,
Jacques Matthee.
DOB = The field Name
BDAYS = The table name

SELECT DOB, CAST(MONTH(DOB) AS VARCHAR(2)) + '-' + CAST(DAY(DOB)AS VARCHAR(2)) + '-' + CAST(YEAR(GETDATE()) AS VARCHAR(4))
FROM BDAYS
WHERE CAST(MONTH(DOB) AS VARCHAR(2)) + '-' + CAST(DAY(DOB)AS VARCHAR(2)) + '-' + CAST(YEAR(GETDATE()) AS VARCHAR(4))
BETWEEN
GETDATE() AND GETDATE() + 30|||Originally posted by r937
select id
, name
, dob
from employees
where datediff(dd
, getdate()
, cast(convert(char(4),year(getdate()) & '/'
& convert(char(5),dob,101)
as datetime)
) <= 30

This may not work at the end of the year. It will skip the people born on January.|||your right

he should test on the month and
add an OR for a test on the next year|||Originally posted by Karolyn
your right

he should test on the month and
add an OR for a test on the next year

I guess this should work. BETWEEN is the best way to go

DOB = The field Name
BDAYS = The table name

====================================
SELECT DOB, CAST(MONTH(DOB) AS VARCHAR(2)) + '-' + CAST(DAY(DOB)AS VARCHAR(2)) + '-' + CAST(YEAR(GETDATE()) AS VARCHAR(4))
FROM BDAYS
WHERE CAST(MONTH(DOB) AS VARCHAR(2)) + '-' + CAST(DAY(DOB)AS VARCHAR(2)) + '-' + CAST(YEAR(GETDATE()) AS VARCHAR(4))
BETWEEN
GETDATE() AND GETDATE() + 30
===============================|||of course my query handles the year-end january boundary!!

however, it did have a few typos in it :rolleyes:

and the test has to be between 0 and 30, not just less than or equal to 30

so in the meantime, i have tested it

this works --select id
, name
, dob
from employees
where datediff(dd
, getdate()
, cast(
cast(year(getdate()) as char(4))
+ '/' + convert(char(5),dob,101)
as datetime)
) between 0 and 30|||Even though you have added BETWEEN in the WHERE clause it still would not work!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Not only for January it would not work if the day falls 30 behind the dates

The DateDiff function would return minus values also.

By the way Toronto is nice city. I used live for a year and half. I love that city

Originally posted by r937
of course my query handles the year-end january boundary!!

however, it did have a few typos in it :rolleyes:

and the test has to be between 0 and 30, not just less than or equal to 30

so in the meantime, i have tested it

this works --select id
, name
, dob
from employees
where datediff(dd
, getdate()
, cast(
cast(year(getdate()) as char(4))
+ '/' + convert(char(5),dob,101)
as datetime)
) between 0 and 30|||you're absolutely right, and i am wrong

i withdraw my solutions

not enough coffee, i guess

i do have a solution, which also prints out the actual age of the person as well, but it was done in access, so i would need a few moments to convert it to sql server syntax

see http://www.dbforums.com/showthread.php?threadid=659590

let me know if you want the conversion|||Where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, @.BirthDate, getDate()), @.BirthDate)))-1 between 0 and 30

Itz ya birf-day!|||Originally posted by blindman
Where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, @.BirthDate, getDate()), @.BirthDate)))-1 between 0 and 30
that is brilliant

it took me about an hour to figure it out and play with it against my test table of birthdays, starting from the innermost function and working out, to see how it works

that formula is fabulous

did you write that?|||Yeah. I took the challenge because the problem looked so deceptively simple. I started with the idea of some ad-hoc implementation of modulo arithmetic, and then simplified it down to the datepart method while I was driving in my car to get some lunch.

It's amazing how many complex programming problems can be solved behind a steering wheel that couldn't be solved in front of a monitor.

I'm not sure how it works around leap years. The dateadd(year, datediff(year, @.BirthDate, getDate()), @.BirthDate) function is supposed to account for it, but it may still be 1 day off.|||Originally posted by blindman
Yeah. I took the challenge because the problem looked so deceptively simple. I started with the idea of some ad-hoc implementation of modulo arithmetic, and then simplified it down to the datepart method while I was driving in my car to get some lunch.

It's amazing how many complex programming problems can be solved behind a steering wheel that couldn't be solved in front of a monitor.or in the bathtub

it works fine around leap years:
...dob... ..today... bdaythisyr adj bdayadjust day
1977-12-09 2004-01-31 2004-12-09 -30 2004-11-09 313
1977-12-10 2004-01-31 2004-12-10 -30 2004-11-10 314
1977-12-11 2004-01-31 2004-12-11 -30 2004-11-11 315
1977-12-29 2004-01-31 2004-12-29 -30 2004-11-29 333
1977-12-30 2004-01-31 2004-12-30 -30 2004-11-30 334
1977-12-31 2004-01-31 2004-12-31 -30 2004-12-01 335
1978-01-01 2004-01-31 2004-01-01 -30 2003-12-02 335
1978-01-02 2004-01-31 2004-01-02 -30 2003-12-03 336
1978-01-03 2004-01-31 2004-01-03 -30 2003-12-04 337
1978-01-04 2004-01-31 2004-01-04 -30 2003-12-05 338
1978-01-05 2004-01-31 2004-01-05 -30 2003-12-06 339
1979-01-10 2004-01-31 2004-01-10 -30 2003-12-11 344
1980-02-04 2004-01-31 2004-02-04 -30 2004-01-05 4
1980-02-05 2004-01-31 2004-02-05 -30 2004-01-06 5
1980-02-06 2004-01-31 2004-02-06 -30 2004-01-07 6
1980-02-28 2004-01-31 2004-02-28 -30 2004-01-29 28 <--
1980-02-29 2004-01-31 2004-02-29 -30 2004-01-30 29 <--
1980-03-01 2004-01-31 2004-03-01 -30 2004-01-31 30 <--
1984-06-14 2004-01-31 2004-06-14 -30 2004-05-15 135|||If you like it, put it on your web page.

That way I'll be able to find it if I ever need it!

Cheers!|||thanks, i will

:cool:|||It will be my greatest honor to have my code engraved in the Book Of Limeback!|||attribution to: blindman

or any other name if you wish (contact me via email)|||Originally posted by blindman
Where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, @.BirthDate, getDate()), @.BirthDate)))-1 between 0 and 30

Itz ya birf-day!

Blindman could you help me out plz?

I have applied your coding as:

Where datepart(dy, dateadd(d, -datepart(dy,Date())+1, dateadd(year, datediff(year, @.MemberExpiryDate, Date()), @.MemberExpiryDate)))-1 between 0 and 30

I get an error message saying,

Syntax error (missing operator) in query expression'Where datepart(dy, dateadd(d, -datepart(dy,Date())+1, dateadd(year, datediff(year, @.MemberExpiryDate, Date()), @.MemberExpiryDate)))-1 between 0 and 30'.

What shall I do to correct this? I am writing this in Access and have been told to change GetDate to Date.|||Is this an Access database or an Access Data Project connected to a SQL Server database?

Access syntax is slightly different than SQL for many functions, including the datepart function.

Where datepart("y", dateadd("d", -datepart("y",Date())+1, dateadd("yyyy", datediff("yyyy", @.MemberExpiryDate, Date()), @.MemberExpiryDate)))-1 between 0 and 30

...but I'm concerned about how you are passing the @.MemberExpiryDate parameter and how you are planning to execute the sql code.|||Using Access, I prefer to get the next anniversary of a given date using:DateAdd("yyyy",DateDiff("yyyy",[dob],Now())+IIf(Format(Now(),"mmdd")<Format([dob],"mmdd"),0,1),[dob])Once you've got that, you can do simple date compares to get the rows that interest you.

-PatP|||Originally posted by blindman
Is this an Access database or an Access Data Project connected to a SQL Server database?

Access syntax is slightly different than SQL for many functions, including the datepart function.

Where datepart("y", dateadd("d", -datepart("y",Date())+1, dateadd("yyyy", datediff("yyyy", @.MemberExpiryDate, Date()), @.MemberExpiryDate)))-1 between 0 and 30

...but I'm concerned about how you are passing the @.MemberExpiryDate parameter and how you are planning to execute the sql code.

This is an Access database.

I have used the following code posted below and it seems to be working.

SELECT member_name, member_id
from your_table
where join_date <= now() + 20

What do you make of it?|||Originally posted by hali99
This is an Access database.

I have used the following code posted below and it seems to be working.

SELECT member_name, member_id
from your_table
where join_date <= now() + 20

What do you make of it? I read that as "show me the members that plan to join sometime in the next 20 days" which isn't quite what I think you want! At least if your join_date column shows the date that the member originally joined.

If I read that correctly, I'd use something like:SELECT member_name, member_id
from your_table
where DateAdd("yyyy",DateDiff("yyyy",[join_date],Now())
+ IIf(Format(Now(),"mmdd")<Format([join_date],"mmdd"),0,1),[join_date]) BETWEEN now() -2 AND now() + 20This will show you the members who expired in the last two day and the members that will expire in the next 20 days.

-PatP|||Where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, @.BirthDate, getDate()), @.BirthDate)))-1 between 0 and 30blindman, somebody emailed me that this isn't working correctly (if you recall, it's on my web site)

i have tested it and have confirmed that it's broken

create table birthdays
( id tinyint not null primary key identity
, birthday datetime
)
insert into birthdays (birthday) values ('1926-12-26')
insert into birthdays (birthday) values ('1927-12-27')
insert into birthdays (birthday) values ('1928-12-28')
insert into birthdays (birthday) values ('1929-12-29')
insert into birthdays (birthday) values ('1930-12-30')
insert into birthdays (birthday) values ('1931-12-31')
insert into birthdays (birthday) values ('1951-01-01')
insert into birthdays (birthday) values ('1952-01-02')
insert into birthdays (birthday) values ('1953-01-03')
insert into birthdays (birthday) values ('1954-01-04')
insert into birthdays (birthday) values ('1955-01-05')
insert into birthdays (birthday) values ('1956-01-06')
insert into birthdays (birthday) values ('1957-01-07')

select * from birthdays
where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, birthday, getDate()), birthday)))-1
=0
1929-12-29 00:00:00.000

select * from birthdays
where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, birthday, getDate()), birthday)))-1
between 0 and 1
1929-12-29 00:00:00.000
1930-12-30 00:00:00.000

select * from birthdays
where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, birthday, getDate()), birthday)))-1
between 0 and 2
1929-12-29 00:00:00.000
1930-12-30 00:00:00.000
1931-12-31 00:00:00.000

select * from birthdays
where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, birthday, getDate()), birthday)))-1
between 0 and 3
1929-12-29 00:00:00.000
1930-12-30 00:00:00.000
1931-12-31 00:00:00.000

select * from birthdays
where datepart(dy, dateadd(d, -datepart(dy, GetDate())+1, dateadd(year, datediff(year, birthday, getDate()), birthday)))-1
between 0 and 4
1929-12-29 00:00:00.000
1930-12-30 00:00:00.000
1931-12-31 00:00:00.000
1951-01-01 00:00:00.000

it seems to mess up on the year boundary|||I'll check it out. Thanks.|||This should work, but slightly differently:set nocount on

create table AnniversaryDates
( id tinyint not null primary key identity
, AnniversaryDate datetime
)
insert into AnniversaryDates (AnniversaryDate) values ('1926-12-26')
insert into AnniversaryDates (AnniversaryDate) values ('1927-12-27')
insert into AnniversaryDates (AnniversaryDate) values ('1928-12-28')
insert into AnniversaryDates (AnniversaryDate) values ('1929-12-29')
insert into AnniversaryDates (AnniversaryDate) values ('1930-12-30')
insert into AnniversaryDates (AnniversaryDate) values ('1931-12-31')
insert into AnniversaryDates (AnniversaryDate) values ('1951-01-01')
insert into AnniversaryDates (AnniversaryDate) values ('1952-01-02')
insert into AnniversaryDates (AnniversaryDate) values ('1953-01-03')
insert into AnniversaryDates (AnniversaryDate) values ('1954-01-04')
insert into AnniversaryDates (AnniversaryDate) values ('1955-01-05')
insert into AnniversaryDates (AnniversaryDate) values ('1956-01-06')
insert into AnniversaryDates (AnniversaryDate) values ('1957-01-07')

declare @.CurrentDate datetime
set @.CurrentDate = '2005-12-28'

select AnniversaryDate,
dateadd(year, datediff(year, AnniversaryDate, @.CurrentDate) + cast(datediff(d, dateadd(year, datediff(year, AnniversaryDate, @.CurrentDate), AnniversaryDate), @.CurrentDate) + abs(datediff(d, dateadd(year, datediff(year, AnniversaryDate, @.CurrentDate), AnniversaryDate), @.CurrentDate)) as bit), AnniversaryDate) as NextAnniversaryDate,
datediff(d, @.CurrentDate, dateadd(year, datediff(year, AnniversaryDate, @.CurrentDate) + cast(datediff(d, dateadd(year, datediff(year, AnniversaryDate, @.CurrentDate), AnniversaryDate), @.CurrentDate) + abs(datediff(d, dateadd(year, datediff(year, AnniversaryDate, @.CurrentDate), AnniversaryDate), @.CurrentDate)) as bit), AnniversaryDate)) as DaysToAnniversaryDate
from AnniversaryDates

drop table AnniversaryDates
Using @.CurrentDate allows you to test four consecutive years to verify no problems with leap years, and also allows you to create the formula as a UDF.

Monday, February 20, 2012

list all employees that didnt take courses in 2005 (was "SQL statment")

I need help on the SQL statment.

This SQL statment is extreamly slow and i don't know how to make it run faster. I have a tblTrainingStudents table where it keeps all the employees trainings and tblSHPEmployee is the employee roster and tblBasicSchool is the table where we track all the cadets who graduate from the basic school (from cadets to troopers) in each year. What i want the result to be is list all employees that didn't take courses in say year 2005. New troopers don't have to take any extra courses for year 2005 since they took these course when they were in basic school. I really need someone can help me speed up my SQL statment ASAP.

Thanks.

************************************************** **

SELECT *
FROM
(SELECT *
FROM tblTrainingCourses C, tblSHPEmployee
WHERE year = '#currentYear#'
AND (reg_no LIKE '1%'
OR reg_no LIKE '2%'
OR reg_no LIKE '3%')
AND troop = '#troop#'
AND NOT EXISTS
(SELECT *
FROM tblTrainingStudents S
WHERE C.trainingType = S.trainingType
AND C.courseID = S.courseID
AND year = '#currentYear#'
AND reg_no = regNo)) as employee

WHERE employee.reg_no NOT IN
(SELECT regNo
FROM tblBasicschool
WHERE employee.reg_no = regNo
AND left(enddate,4) = '#currentYear#'
AND (rank='TRP' OR left(regNo, 1) = '3'))
************************************************** *********

ORDER BY troop, lname, fname, minit, trainingType, courseIDI don(t see any need for the "SELECT FROM SELECT", so what about:SELECT *
FROM tblTrainingCourses as C, tblSHPEmployee
WHERE year = '#currentYear#'
AND (reg_no LIKE '1%' OR reg_no LIKE '2%' OR reg_no LIKE '3%')
AND troop = '#troop#'
AND NOT EXISTS
(SELECT 1
FROM tblTrainingStudents
WHERE C.trainingType = trainingType
AND C.courseID = courseID
AND year = '#currentYear#'
AND reg_no = regNo)
AND reg_no NOT IN
(SELECT regNo
FROM tblBasicschool
WHERE left(enddate,4) = '#currentYear#'
AND (rank='TRP' OR regNo LIKE '3%')
)
ORDER BY ...Clearly the "NOT EXISTS" and "NOT IN" will potentially slow down the query (since no index can be used for resolving these conditions).
Similarly the use of left(enddate,4) may slow down things; you should (if possible) replace it with someting like "enddate LIKE '2006%'".|||Peter, thanks for your post. It is still so slow. It takes about 3 mins to run the query. Is there any other way to speed this up a lot more? The tblTrainingStudents is kind of big. I really appreciate your help.|||It looks like your main query produces a cartesian product for I don't see a join-clause between 'tblTrainingCourses' and 'tblSHPEmployee'... or did I miss something?

Grts|||What about the following query?
I've removed tblTrainingCourses, and also removed the redundant condition reg_no = regNo in the second subquery.
You will maybe have to re-insert your conditions on year and troop -- I've no idea in which tables they belong.
Also, for the time being, I replaced the "in current year" condition by ">= '2006-01-01'"; adapt this if necessary.
The conditions on reg_no (with "BETWEEN" and ">= '3'") are more performant than a LIKE; but they assume reg_no to be all digits, and moreover assume an ASCII ordering.
Again, adapt if necessary.SELECT *
FROM tblSHPEmployee AS e
WHERE reg_no BETWEEN '1' AND '39999999'
AND NOT EXISTS
( SELECT regNo
FROM tblTrainingStudents AS s INNER JOIN tblTrainingCourses AS c
ON s.CourseID = c.CourseID
WHERE regNo = e.reg_No
AND year = '2006'
)
AND reg_no NOT IN
( SELECT regNo
FROM tblBasicschool
WHERE endDate >= '2006-01-01'
AND (rank = 'TRP' OR regNo >= '3')
)You may replace the "NOT EXISTS" by a "NOT IN" and vice versa; that could give performance differences (depending on the size of the tables), so try out all four possibilities. Don't forget to remove the condition "regNo = e.reg_No" in the "NOT IN" and to add it in the "NOT EXISTS".|||'LIKE' keywords also slow down queries since they force a table scan. Also you're selecting * when you potentially could not be.|||'LIKE' keywords also slow down queries since they force a table scan.Not necessarily: most RDBMS' will use a matching index scan for "LIKE '3%'". But you're right in the case of a "%" at the beginning of the string.
Also you're selecting * when you potentially could not be.This is less of a performance problem, it's at most a data transmission bottleneck (over a slow communication line).
Except in the case where you would only SELECT a column which happens to be an indexed column (or column combination), since in that case the query *could* be performed with an index-only scan (but that also depends on the WHERE condition of course).|||Not necessarily: most RDBMS' will use a matching index scan for "LIKE '3%'". But you're right in the case of a "%" at the beginning of the string.
This is less of a performance problem, it's at most a data transmission bottleneck (over a slow communication line).
Except in the case where you would only SELECT a column which happens to be an indexed column (or column combination), since in that case the query *could* be performed with an index-only scan (but that also depends on the WHERE condition of course).

I defer to your superior knowledge Peter!

Our DBAs here refuse to allow us to use LIKE in code because most of the time it does a table scan. 'SELECT *' is also banned since not only is it wasteful, it has a tendency to stop working if the table schema changes. :D|||'SELECT *' is also banned since not only is it wasteful, it has a tendency to stop working if the table schema changes.I fully agree with that: it's *always* safer to list all required columns explicitly, even it turns out to be all table columns.
So indeed "SELECT *" should be banned!|||I fully agree with that: it's *always* safer to list all required columns explicitly, even it turns out to be all table columns.
So indeed "SELECT *" should be banned!

ITA Peter...we've still got some 'select *' stuff hanging around but it is slowly being re-written to explicitly list all the columns.|||Or if you want to list all courses together with all employees who did not take that course:SELECT c.CourseName, e.EmployeeName
FROM
tblSHPEmployee AS e
INNER JOIN
tblTrainingCourses AS c
ON NOT EXISTS
( SELECT 1
FROM tblTrainingStudents AS s
WHERE s.CourseID = c.CourseID
AND e.reg_No = s.regNo
)
WHERE
reg_no BETWEEN '1' AND '39999999'
ORDER BY 1, 2Mind you that this may again run a lot slower!|||[Non-ANSI Comment]Assuming this is SQL Server then SELECT * within an exists statement is the one time SELECT * is recommended - the optimiser then selects optimal index.[/Non-ANSI Comment]|||SELECT * within an exists statement is recommended - the optimiser then selects optimal index.Are you sure that SQLServer would not do that with "SELECT 1" ?
I know DB2 will typically do an index scan without data lookup when using "SELECT 1".|||You know - I have lost my original MS link but coincidently today I've read something elsewhere (by the bloomin head of SQL Server Optimisation no less) that contradicts what I posted. So disregard :rolleyes:|||Anyway, in an EXISTS, "SELECT 1" is better than "SELECT *" since the former does not require data access (when an index is available on the column(s) specified in the WHERE condition) while the latter may need data access (unless the optimizer is clever enough to see that the two are equivalent :-)

List All Employee under my control

Hi,

I have a table employee with two fields (empId, and Supervisor)

what i want is to list all employees under a given empId

example

Table: Employee
EmpId, Supervisor
1, Null
2, 1
3, 1
4, 2
5, 2
6, 3
7, 4
8, 4
9, 5
10, 5
11, 6
12, 6
13, 6

request of the employees under control of 4?
Result should be: 4, 7, 8

request of the employees under control of 2?
Result should be: 2, 4, 5, 7, 8, 9 , 10

request of the employees under control of 3?
Result should be: 3, 6, 11, 12 , 13

thanks a lotsdeclare @.SupervisorID int
set @.SupervisorID = 3

declare @.Subordinates table (EmpID int)

insert into @.Subordinates (EmpID)
select EmpID
from Employees
where Supervisor = @.SupervisorID

while @.@.Rowcount > 0
insert into @.Subordinates (EmpID)
select Employees.EmpID
from Employees
inner join @.Subordinates Subordinates on Employees.Supervisor = Subordinates.EmpID
where not exists(select * from @.Subordinates CurrentEmpIDs where Employees.EmpID = CurrentEmpIDs.EmpID)

select * from @.Subordinates

blindman