I have an issue writing a query in MS Access that would pull information from two tables.
Quick description:
Employees start the job and click the button in Excel macro. The macro saves the date and a comment that the employee provides (not required). Next, the macro pushes the information into a table in Access database which gathers all 'check-ins' of all employees. There's a possibility for a person to check-in twice by accident. This is an example how the table would look like after two work days, in a company with three employees:
check-in table example
Similarly, the macro lets a user to check-out, also with optional comment:
check-out table example
What I need is a query that would consolidate two of these tables and show check-in/check-out of employees for a previous day, together with provided comment. So the result of the query would look like this:
outcome of a table for previous day
Column order is absolutely irrelevant here
SELECT min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.[comment] AS [check-in comment], checkout.[comment] AS [check-out comment]
FROM checkin
RIGHT JOIN chekout ON checkin.analyst = checkout.analyst
WHERE checkin[check-in time] = Date()-3;
Bad thing is, MS Access throws:
Syntax error in JOIN operation
Could anyone help me out and advise how should I proceed? Unfortunately I have no control how the system was implemented (Macro in Excel connected with Access) and sadly I have not much experience in MS Access.
EDIT:
Thank you very much #Erik, much appreciated. It helped a lot and I'll be more diligent next time when it comes to typos. The new problem presented itself however. It is possible for a person to check-in, without checking-out and vice versa. Lets say there's another row in the first table -> Meg015 checked in at 7:20 on 08.06.2018 but forgot to check out:
see an example
I would like MS Access to present this information accordingly (without forgotten check-out time):
How it should look like
Since there's no Full Outer Join in MS Access, I was thinking about following UNION/LEFT and RIGHT JOINs:
SELECT checkin.analyst, min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.comment, checkout.comment
FROM checkin RIGHT JOIN checkout ON (checkin.analyst = checkout.analyst OR checkout.analyst = NULL OR checkin.analyst = NULL)
WHERE (format(checkin.[check-in time], "Short Date") = format(checkout.[check-out time], "Short Date") OR checkout.[check-out time] = NULL) AND format(checkin.[check-in time], "Short Date") = date()-3
GROUP BY checkin.analyst, checkin.comment, checkout.comment
UNION
SELECT checkout.analyst, min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.comment, checkout.comment
FROM checkin LEFT JOIN checkout ON (checkin.analyst = checkout.analyst OR checkin.analyst = NULL OR checkout.analyst = NULL)
WHERE (format(checkin.[check-in time], "Short Date") = format(checkout.[check-out time], "Short Date") OR checkin.[check-in time] = NULL) AND format(checkin.[check-in time], "Short Date") = date()-3
GROUP BY checkout.analyst, checkin.comment, checkout.comment;
Sadly, Meg's check-in details are not visible in a result of the query above. Any idea how to resolve this issue?
You're missing a dot, have misspelt checkout in your join, and are using aggregates without grouping by the other columns.
Also, you're testing if a date is equal to a date with time, which will pretty much always be false.
Anyway, this is how your query should look like:
SELECT checkout.analyst, min(checkin.[check-in time]), max(checkout.[check-out time]), checkin.[comment] AS [check-in comment], checkout.[comment] AS [check-out comment]
FROM checkin
RIGHT JOIN checkout ON checkin.analyst = checkout.analyst
WHERE DATEDIFF('d',checkin.[check-in time], Date()) = 3
GROUP BY checkout.analyst, checkout.[comment], checkin.[comment]
(Do note that questions with this many errors can get closed as too broad).
Related
In my database I have 1 table - (tbl_RTILog)
I have 1 form that enters the data into this table - (frm_Logger)
I then have a separate form that would update the checkbox in the table - (frm_RTIRev).
My table fields are:
ID - Autonumber
Acc Number - number
MPRN - number
Time Raised - time
Sweep Time - time
Advisor - text
Credit - currency
PayID - text
Reviewer - text
Completed? yes/no
I have a recordset as below in the record source, SELECT tbl_RTILog.[Account Number], tbl_RTILog.MPRN, tbl_RTILog.[Time Raised], tbl_RTILog.[Expected Sweep Time], tbl_RTILog.Advisor, tbl_RTILog.[Credit Amount], tbl_RTILog.[Paypoint ID], tbl_RTILog.[Completed?], tbl_RTILog.ID FROM tbl_RTILog WHERE (((tbl_RTILog.[Completed?])=False)) GROUP BY tbl_RTILog.[Account Number], tbl_RTILog.MPRN, tbl_RTILog.[Time Raised], tbl_RTILog.[Expected Sweep Time], tbl_RTILog.Advisor, tbl_RTILog.[Credit Amount], tbl_RTILog.[Paypoint ID], tbl_RTILog.[Completed?], tbl_RTILog.ID ORDER BY tbl_RTILog.[Time Raised] DESC;
This is filtering the data to only show records where the checkbox returns 'False'.
I have tried changing the recordset type from 'Dynaset' to 'Dynaset (inconsistent updates) and this has made no difference.
All I want to do is for the second form to load (frm_RTIRev) and display all incomplete reviews and then be able to be marked as completed but the 'recordset is no updateable'
Thanks in advance
I have managed to answer my own question in some weird and wonderful unexplainable way.
I recreated the Query and this allowed me to edit the data.
No answer for this apart from that when I remade it it worked straight away.
I have an MS-Access DB that pulls information in from an Excel file with 6 worksheets, so I get 6 tables. I created 7 queries, all of which make tables from the excel data, 6 of those 7 do a count of an item ie:
SELECT DISTINCT DISPLAYNAME, COUNT(DISPLAYNAME)
FROM [TXFR REC]
GROUP BY DISPLAYNAME
The 7th query pulls those 6 tables together into a sort of report table by using left joins onto one of the tables, where the connection to all the others is a DISPLAYNAME.
I have created a Form with 4 buttons and two date boxes, a start date and an end date. What I want to do is the following:
Choose Start Date
Choose End Date
Press Button that runs the 7 queries in the order I specified by invoking the date range from steps 1 and 2 ** THIS IS WHERE I AM STUCK: I do not know how to force this date range on the queries **
Run the report
Export the report
Close the form
The date boxes are set to General Date and the method used for them is GetDates so you just click in the box and the calendar pops up and you choose your date.
I did see this post here but am not following to well:
Date Range Form
Here is the text from a test query as suggested by a user and in the format suggested by the answering person:
SELECT [NO ADMITTING DX (HEALTH ISSUE)].PHYSICIANDISPLAYNAME, Count([NO ADMITTING DX (HEALTH ISSUE)].PHYSICIANDISPLAYNAME) AS CountOfPHYSICIANDISPLAYNAME INTO NO_ADMIT_DX_COUNT
FROM [NO ADMITTING DX (HEALTH ISSUE)]
WHERE ((([NO ADMITTING DX (HEALTH ISSUE)].PHYSICIANDISPLAYNAME) Is Not Null) And (([NO ADMITTING DX (HEALTH ISSUE)].AdmitDtm) Between Forms!PRINT_REPORT![START DATE] And FORMS!PRINT_REPORT![END DATE]))
GROUP BY [NO ADMITTING DX (HEALTH ISSUE)].PHYSICIANDISPLAYNAME;
** This query now works properly **
Thank you for all the help.
For your query, use something like this.
SELECT DISPLAYNAME, COUNT(DISPLAYNAME)
FROM [TXFR REC]
WHERE [TXFR REC].yourDate BETWEEN [Forms]![yourFormName]![yourStartDate]
AND [Forms]![yourFormName]![yourEndDateField]
GROUP BY DISPLAYNAME
All of your queries that you want to rely on a date range should have these parameters. The advantage to doing it this way is that you can give your two date fields on your form a datePicker. It would still work the same if you did something like this:
SELECT DISPLAYNAME, COUNT(DISPLAYNAME)
FROM [TXFR REC]
WHERE [TXFR REC].yourDate BETWEEN [Please Enter a Start Date]
AND [Please Enter an Ending Date]
GROUP BY DISPLAYNAME
It's all preference though. Just throw a button on there and go to Misc in the wizard and choose run query if you want.
Edit your queries to rely on the value of the form in the where clause:
[Forms]![form's name]![form's control]
Here's a Screenshot example
This will make your queries only work with the form, however. You might consider copying your queries and renaming and editing the copies to reflect its limitation.
I have a report which grabs a whole bunch of statistical data that represent system alarms.
I've made a drilldown style report by pulling back all the stats in a user selected date range and then I added a group on my alarm's codeId so I would have something to group on.
What I would like to do is have a count of the number of items within these groups by codeId. I plan to use the count as part of a concatenated string that makes up the whole group header. It basically says "Alarm Code # {codeId} - {Description} - Total: {Total}".
My issue is that to do a count in my query then I have to pre-group the data before it hits the report. And if I do that then I do not have my detail data to expand the group on. And running a summary and a detail dataset is a bit over my head but an option I might have to look into.
So I was hoping I could use a group variable to count the number of items contained within the group. Can anyone tell me a rough set of steps to try to pull that off?
Seems like using a Group variable here would make this more complicated than it needs to be.
Since you already have a group in SSRS, you can use the CountRows function. Put this expression into a placeholder, for example:
="Alarm Code #" & Fields!CodeID.Value
& " - " & First(Fields!Description)
& " - Total: " & CountRows()
Or, depending on size, you can add a correlated subquery to your SQL query:
SELECT
CodeID,
MyField,
MyOtherField,
(SELECT COUNT(*) FROM myTable t1 WHERE t1.CodeID = t2.CodeID) AS MyRowCount
FROM
myTable t2
This is not particularly efficient SQL, so if you are running this on hundreds of thousands of rows or more, I'd go with the first approach.
As the title says, I'm looking for a way to calculate the percentage of completed tasks a person has. Data is structured so that each individual has can have many tasks, and each task can have many sub-tasks, as described below:
Employees
(pk)(AutoNumber)employee_id
(Text)FirstName
(Text)LastName
Tasks
(pk)(AutoNumber)task_id
(fk)(Number)employee_id
(Memo)Description
(Yes/No)Completed
Sub-Tasks
(pk)(AutoNumber)subtask_id
(fk)(Number)task_id
(Memo)Description
(Yes/No)Completed
I've been trying to make a report (named "Task Completion Rates") that lists all employees, the number of completed tasks they have, the total number of tasks they have, and their completion rate as a percentage. At the moment, I have the following two queries:
SELECT Count(employee_id) FROM [Tasks] AS TotalTasks WHERE [Tasks].employee_id =
Reports![Task Completion Rates]!txt_employeeID
SELECT Count(employee_id) FROM [Tasks] AS CompletedTasks WHERE [Tasks].employee_id = Reports![Task Completion Rates]!txt_employeeID AND [Tasks].Completed = 1
Are both of those necessary, or is there a way to get both counts from one query? Also, how would I go about using those totals in the report? The report's Record Source is set to the Employees table so that it can list them all. I've got text boxes ready to go for each total, but I'm having problems using the expression builder in the source for each text box to actually display the results of the queries. I set the source for one of the text boxes to =[qry_TotalTasksPerEmployee]![TotalTasks] (via expression builder) but it keeps prompting me to enter a value for [qry_TotalTasksPerEmployee]. Any ideas on how get this working?
Try taking the mean of your completed value. For example:
SELECT employee_id, -avg(Completed) FROM [Tasks] GROUP BY employee_id
The - before avg is because true is stored as -1, as pointed out by #Neil.
I'm not sure what you mean about the report - it should be easy to place query results in a report.
I'm not really into msaccess reports but since completed seems to be either a 0 or a 1 you should work towards the following query
-Edit turns out it's either 1 or -1 for bools so can't do a sum(completed) but need an IIF()
Select employee_id, count(*), sum(IIF(completed,1,0)), sum(IIF(completed,1,0))*100/count(*) as rate
From employees
Left join tasks
On tasks.employee_id = employees.employee_id
Group by employee_id
Note that this does create a division by zero problem for employees without tasks. You will have to deceide how to deal withbthose (exclude, show as 0% or ...)
I have an Access 2000 report based on a query like this
SELECT
...
FROM Clients AS wc INNER JOIN ...
WHERE ((wo.OfferStatusID)=3) AND
((DatePart("ww",[wo.StatusTimeStamp]))=DatePart("ww",[Enter Week End Date]))
AND ((Year([wo.StatusTimeStamp]))=Year(Date())));
The where clause allows you to enter the 'Week End Date' and it finds all of the records for the Sunday-Saturday week that contains the end date.
My problem is I need to include the Saturday end date on the report so that the header reads '... for week ending 5/9/09' and I can't figure out how to get that date without the query asking me for it a second time.
Is there a way to force Access to return the parameter entered as another field in the results, or another way to get that week ending date?
Continuing to poke around in the query designer I discovered that I could add this to the SELECT clause and get the value entered added to each row:
[Enter Week End Date] AS WeekEndDate
This works, but I am still open to other suggestions.
You could stack two queries (make one the source of the other). This would be pretty MS Access'y. However, if you have it working now, I'd stick with what you have. It's probably cleaner.
Another approach is to use a form to grab the query params first, and reference the form control in the query. For instance, with your example, create a form called frmGetDateParam, and add a textbox called txtDate. Change the format to a date, perhaps add some validation, doesn't matter. Add a command button to the form which opens up the report. Then, change your query to look like this :-
SELECT
...
FROM Clients AS wc INNER JOIN ...
WHERE ((wo.OfferStatusID)=3) AND
((DatePart("ww",[wo.StatusTimeStamp]))=DatePart("ww",Forms!frmGetDateParam!txtDate))
AND ((Year([Forms!frmGetDateParam!txtDate]))=Year(Date())));
You can also reference Forms!frmGetDateParam!txtDate as a field on your report.
The only downside to this approach is that if you try to open the query/report without the parameter form being open, then the query will still prompt you for the date value.