How to Query attendance on MS-ACCESS - ms-access-2007

I want to query an attendance from ms-access with one table on it and calculate the number of hrs work :
emp_id emp_name emp_date emp_time emp_dept emp_mode
1 mike 20140819 201040 security 5
1 mike 20140820 051005 security 4
2 tess 20140819 074910 hr 5
2 tess 20140819 171011 hr 4
Now, I want to display them like this :
emp_id emp_name emp_date time-in time-out HrsWork
1 mike 20140819-20140820 210010 051005 9
2 tess 20140819-20140819 075910 171011 10
Any help would be appreciated. Thanks

Keep in mind that using ctrl+k will allow you to type using code lines, which will help you keep things lined up.
I say this because it took me about an hour to fully understand what you posted at the top. The line below:
emp_id emp_name emp_date emp_time emp_dept emp_mode
1 mike 20140819 201040 security 5 1 mike 20140820 051005 security 4 2 tess 20140819 074910 hr 5 2 tess 20140819 171011 hr 4
should translate to:
emp_id emp_name emp_date emp_time emp_dept emp_mode
1 mike 2014/08/19 20:10:40 security 5
1 mike 2014/08/20 05:10:05 security 4
2 tess 2014/08/19 07:49:10 hr 5
2 tess 2014/08/19 17:10:11 hr 4
Which then gave me a better understanding of what you were trying to accomplish.
but we all live and learn. I think you are looking for something like the below SQL statement.
SELECT HourCalc.emp_id, HourCalc.emp_name, HourCalc.StartDateTime, HourCalc.EndDateTime, DateDiff('n',[startdatetime],[enddatetime])/60 AS HrsWorked
FROM (SELECT t1.emp_id, t1.emp_name, CDate([emp_date] & ' ' & [emp_time]) AS StartDateTime,
(SELECT MIN(cdate(t2.emp_date & ' ' & t2.emp_time))
FROM emptable t2
WHERE t2.Emp_id = t1.Emp_ID
AND cdate(t2.emp_date & ' ' & t2.emp_time) > cdate(t1.emp_date & ' ' & t1.emp_time)
AND emp_mode = '4') AS EndDateTime
FROM emptable AS t1
WHERE (((emp_mode) = '5'))) as HourCalc;
On each where clause, if your emp_mode is a number field data type, just remove the single quotes around the number 4 and 5.
This might not be the exact layout you posted in your question, but it should put you on the right track.
If this doesn't work, let me know and we can do more digging to find you the correct SQL statement you are looking for.

Related

MS Access: How do I find an employee with the latest date with "Working" or "Reinstated" status only?

tbl_emp_mast
emp_no emp_last_name emp_first_name
1 smith john
2 doe jane
3 case justin
tbl_emp_st
emp_no st_date emp_st
1 10/01/2020 WORKING
1 10/05/2020 QUIT
1 10/10/2020 REINSTATED
2 10/07/2020 QUIT
3 10/02/2020 WORKING
For the purpose of the combo box in the form, I wanted only those employees who are currently working. So, there should be employees # 1 and 3 from the query result.
I tried this:
SELECT tbl_emp_mast.emp_no AS tbl_emp_mast_emp_no, tbl_emp_mast.emp_last_name & ", " & tbl_emp_mast.emp_first_name AS Employee, tbl_emp_st.st_date, tbl_emp_st.emp_st
FROM tbl_emp_mast INNER JOIN tbl_emp_st ON tbl_emp_mast.[emp_no] = tbl_emp_st.[emp_no];
Thank you.
Hmmm . . . I think you want the most recent emp_st. If so, then I think:
select es.*
from tbl_emp_st as es
where es.st_date = (select max(es2.st_date)
from tbl_emp_st as es2
where es2.emp_no = es.emp_no
) and
es.emp_st in ('WORKING', 'REINSTATED');
You should add a WHERE clause to check that the latest date for each tbl_emp_st is a row where emp_st is not equal to 'QUIT':
SELECT m.emp_no AS tbl_emp_mast_emp_no,
m.emp_last_name & ', ' & m.emp_first_name AS Employee,
s.st_date,
s.emp_st
FROM tbl_emp_mast AS m INNER JOIN tbl_emp_st AS s
ON m.emp_no = s.emp_no
WHERE s.st_date = (SELECT MAX(st_date) FROM tbl_emp_st WHERE emp_no = m.emp_no)
AND s.emp_st <> 'QUIT'
Results:
tbl_emp_mast_emp_no Employee st_date emp_st
1 smith, john 10/10/2020 REINSTATED
3 case, justin 10/02/2020 WORKING

Is there a way to list the most recent dates for an event based on data in other columns?

I am working to write a query that shows the most recent job start date for each person with extended families with in the past year (I should not show future dates) It is possible that multiple families (in multiple states) may have started their job on the same date. In that case, I need to list the state(s), both people, and the respective dates. However, I should only list each state/person pair once.
Additionally, if the person didn't start their job within the past year, I should still list the persons name but in the place of the state name, I should have the query return NULL and the date return NULL.
Below is the date in the raw table:
LOC FAM PPL MILESTONE_ID MILESTONE_NAME START_DATE
WI Smith Mike 1 End College 9/4/2017 0:00
WI Smith Mike 2 Start Job 9/4/2017 0:00
WI Smith Bob 1 End College 6/4/2019
WI Smith Bob 2 Start Job 6/4/2019
IL Thomas Mike 1 End College 1/4/2019
IL Thomas Mike 2 Start Job 6/4/2019
IL Thomas Bob 1 End College 12/4/2019
IL Thomas Bob 2 Start Job 6/4/2019
I know that I need to use a subquery to get the most recent job start dates but my subquery isn't behaving as expected. I have also tried using a CTE but that isn't working either.
This is what I have so far. I haven't gotten the subquery to work correctly. I still need to add the NULL portion of the situation above
Select family.*
From
FAMILY.KEYINFO as family
Inner Join
(Select family.milestone_id, MAX(family.start_date) as LatestDate
from FAMILY.keyinfo
group by milestone_id) groupeddate
on family.milestone_id=groupeddate.milestone
where family.start_date<= CURRENT_TIMESTAMP
and family.start_date > DATEADD(year,-1,GETDATE())
Below is what I would expect the answer to be if the query was correct:
LOC PPL START_DATE
N/A Mike N/A
N/A Mike N/A
WI Bob 6/4/2019
IL Mike 6/4/2019
IL Bob 6/4/2019
You seem to want window functions:
select f.*
from (select f.*,
rank() over (partition by fam order by start_date desc as seqnum
from families f
where milestone_name = 'Start Job'
) f
where seqnum = 1;

SQL- Write script to show project name and dates

I'm new to SQl and just going through some exercises. I'm trying to do scripts but need some assistance and would appreciate if someone can help me with the below topic which I am stuck on.
Table structure
**Project**
ID(PK) NAME Due_Date
1 Alpha 1/1/2040
2 Bravo 3/1/2030
3 Charlie 2/1/2017
4 Delta 4/1/2017
*Employee*
ID(PK) NAME
1 Kevin
2 Mike
3 Eric
4 Ira
5 Peter
*Project Assignment*
ID(PK) ProjectID(FK) EmployeeID(FK)
1 1 1
2 1 2
3 2 2
4 2 3
5 3 3
6 3 4
7 1 3
Question
Write a script that will return all project names and how much time (in days) is left until they are due for all projects which have not been completed yet.
If your question is asked correctly, then you only need the projects table. But I doubt that is what you want.
SELECT Name,
DATEDIFF (DAY, GETDATE(), Due_Date) AS DaysRemaining
FROM Project
WHERE Due_Date > GETDATE()
If you need employee data included, please adjust your question.
From my understanding i do this,
select pa.ID,e.NAME,p.NAME,p.Due_Date, DATEDIFF (DAY, GETDATE(), Due_Date) AS
DaysRemaining from
Project_Assignment pa inner join project p
on pa.projectid = p.id
inner join Employe e
on pa.EmployeeID = e.ID
and p.due_date > getdate()
Revert me any clarifications needed...

Querying 100k records to 5 records

I have a requirement in such a way that it should join two tables with more than 100k records in one table and just 5 records in another table as shown below
Employee Dept Result
id Name deptid deptid Name Name deptid Name
1 Jane 1 1 Science Jane 1 Science
2 Jack 2 2 Maths Dane 1 Science
3 Dane 1 3 Biology Jack 2 Maths
4 Drack 3 4 Social Drack 3 Biology
5 Drim 5 Zoology Kery 4 Social
6 Drum 5 Drum 5 Zoology
7 Krack
8 Kery 4
.
.
100k
Which join need to be used to get the query in an better way to perform to get the result as shown.
I just want the query to join with other table from employee table only which has dept which i thought of below query but wanted to know is there any better way to do it.
Select e.name,d.deptid,d.Name from
(Select deptid,Name from Employee where deptid IS NOT NULL) A
and dept d where A.deptid=d.deptid;
Firstly not sure why you are performing your query the way you are. Should be more like
SELECT A.name, D.deptid,D.Name
FROM Employee A
INNER JOIN dept D
ON A.deptid = D.deptid
No need of the IS NOT NULL statement.
If this is a ONE TIME or OCCASIONAL thing and performance is key (not a permanent query in your DB) you can leave out the join altogether and do it using CASE:
SELECT
A.name, A.deptid,
CASE
WHEN A.deptid = 1 THEN "Science"
WHEN A.deptid = 2 THEN "Maths"
...[etc for the other 3 departments]...
END as Name
FROM Employee A
If this is to be permanent and performance is key, simply try applying an INDEX on the foreign key deptid in the Employee table and use my first query above.

SQL Reports - sorting an column based on the date mentioned in another column adjacent to it

It would be great if someone can help me out. I am new to SQL.
This is what my table data is
table name: emp
e_no e_name e_jobrole position promotion_date
1 Robin Sales CEO 01/01/2012
1 Robin Sales CFO 20/01/2010
2 Jackman Sales - S1 EMP 01/04/2009
4 Sheldon Marketing MGR 15/08/2012
4 Sheldon Marketing SNRMGR 01/01/2011
4 Sheldon Marketing MGR 01/01/2011
3 Arnold Marketing CEO 09/09/2009
5 Emmy Marketing SNRMGR 08/08/2008
6 Penny Admin SNRMGR 05/05/2012
6 Penny Admin MGR 09/09/2007
By ordering through the date these guys promoted, I need to capture the previous position held by the employee and adjacent to that current position. Is this possible ?
Below is what I required as Output
e_no e_name e_job prev_pos curr_pos promotion_date
1 Robin Sales CFO CEO 01/01/2012
2 Jackman Sales - S1 Not Available EMP 01/04/2009
4 Sheldon Marketing MGR MGR 15/08/2012
3 Arnold Marketing Not Available CEO 09/09/2009
5 Emmy Marketing Not Available SNRMGR 08/08/2008
6 Penny Admin MGR SNRMGR 05/05/2012
EDIT: I seem to have been proven wrong just seconds after posting :P
I don't think you can do that in one query (except using a complicated stored procedure).
How about getting the data into an application (in Java, or whatever you would like) and then parse the data from the oldest data, and keeping track of the "previous position" of each employee. Then, whenever you get to one that you've already got a "previous position" for you can insert that into the table, and update the "previous position" (and if you haven't seen her before, set the "previous position" to null/"none"/""/etc).
Would that be useful, or would it have to be all done on the DB?
Something like this should work. The combination of WHERE and HAVING may need some adjustment.
select
c.e_no,
c.e_name,
c.e_job,
p.position as prev_position,
c.position as curr_position,
c.promotion_date
from
emp c
inner join
emp p
on
c.e_no=p.e_no
group by
c.e_no,
c.e_name,
c.e_job,
p.position as prev_position,
c.position as curr_position,
where
p.promotion_date < c.promotion_date
having
max(p.promotion_date),
max(c.promotion_date)