MS Access - Query - Required Forms for Each Employee - sql

I have 3 tables, all SharePoint lists. I am trying to create a query that will show me all of the required DQ_File Forms that do not have an attachment in the DQ_File.
DQ_File_Lookup is a lookup table for the description field in the DQ_File. It also has the "DQRequired" flag I am looking for to see all of the required fields that do not have an attachment.
I have included a screen shot showing the table layouts and relations.
Any help would be appreciated, I am sure I am just overlooking something obvious.
A example would be as follows:
Employee Name | Document Name
You would have employee Joe and he has forms A,B,D out of a possible forms A,B,C,D,E,F so he would be missing forms C,E and F.
So the employee name would come from the employee table, and the document name needs to get passed through the DQ_File Table from the DQ_File_Lookup
the way I thought to do it was to get it to show all documents from the DQ_File table that are missing, that I can do. But that only shows the information that has an entry. There are certain forms that are required for every employee that I want to be able to see if a employee is missing any of those forms.
Using what #June7 posted below I got it to work, and it now will show me all 15 documents that are required for every driver. But when I add the attachment field from DQ_File it shows them all as zero attachments, when I know some of them do indeed have attachments already.
Here is a screen cap showing this.
Williams in particular should only have about 5 documents that should be on this list, but instead it is showing like all 15 are missing.
Here is the SQL from the combined query:
SELECT [qryEmployees+DQFileLookup].Last, [qryEmployees+DQFileLookup].Description, DQ_File.Attachment
FROM DQ_File RIGHT JOIN [qryEmployees+DQFileLookup] ON DQ_File.EmployeeNo = [qryEmployees+DQFileLookup].EmployeeCode
WHERE (((DQ_File.Attachment.FileURL) Is Null) AND (([qryEmployees+DQFileLookup].CURRENT)=True) AND (([qryEmployees+DQFileLookup].DRIVER)=True) AND (([qryEmployees+DQFileLookup].DQRequired)=True));

If you want to know which required docs employees do not have, then need a dataset of all possible combinations of employees/docs. Then match that dataset with DQ_File to see what is missing. The all combinations dataset can be generated with a Cartesian query (a query without JOIN clause) - every record of each table will associate with every record of other table.
SELECT Employees.*, DQ_File_Lookup.* FROM Employees, DQ_File_Lookup;
Then join that query with DQ_File.
SELECT Query1.EmployeeID, Query1.First, Query1.Last, Query1.ID, Query1.Title, Query1.DQRequired, DQ_File.Description, DQ_File.EmployeeNo
FROM DQ_File RIGHT JOIN Query1 ON (DQ_File.EmployeeNo = Query1.EmployeeID) AND (DQ_File.Description = Query1.ID)
WHERE (((Query1.DQRequired)=True) AND ((DQ_File.EmployeeNo) Is Null));
Advise not to use exact same field names in multiple tables. For instance, Title in DQ_File_Lookup could be DocTitle and Title in Employees could be JobTitle. And there will be less confusion if ID is not used as name in all tables.
It seems unnecessary to repeat Title and [Compliance Asset ID] in all 3 tables.
Strongly advise not to use spaces in naming convention. Title case is better than all upper case.

Related

How to make a lookup query to another table filter out records based on existing relationships between tables without macros?

Given those relationships, how do I limit the choice of Leader in a given record in GroupResults to only those StudentResults.IDs, which have Class&Group set to the same value as in the ID field of that record without creating forms and using VBA?
If I assign SELECT StudentResults.ID, StudentResults.FullName FROM StudentResults; to the Row Source in [Leader], like this ,
I get all the records in the table to choose from, regardless of the [Class&Group] field value, like this .
How do I restrict the assignable records to only those that belong to the corresponding group?
I'd spent a very long time trying to find a way to run a parametrised SQL query to pass the [Class&Group] to the WHERE clause, but eventually had to give up.
Thank you very much for your help!
P.S. I do realise that this may or may not be more of an ms-access, rather than SQL question.
Tables are not designed to be user interfaces. Conditional comboboxes, validation, etc. work best on forms. Comboxbox lookup dropdowns are more an Access GUI convenience to show parent table indicators for key number values.
When queries are then run from such tables, these drop downs fields show to help us humans who naturally understand names and indicators rather than integer primary/foreign keys. So instead of Student: 1, we see Student: John Doe. In fact, such table field drop downs even helps generate the same comboboxes on Access forms and reports in advance to avoid the designer in building them upon clicking the form icons on ribbon.
However, for your needs consider adjusting combobox by showing the [Class&Group] field so the user can see or match the group of specific Leader with appropriate one for current record in Class column. See adjusted query and column count/heads.
Row Source: SELECT s.ID, s.[Class&Group], s.FullName FROM StudentResults s
Bound Column: 1
Column Count: 3
Column Heads: Yes
Also, if you want the Leader name to always show when table or query is opened instead of ID, reverse the order in query and change bound column:
Row Source: SELECT s.FullName, s.[Class&Group], s.ID FROM StudentResults
Bound Column: 3
Column Count: 3
Column Heads: Yes

multiple Access queries using same criteria

New to this...
I have a table QAQC_Studies that includes titles, dates, and subject matter
I have another table QAQC_Publications that includes citation information for multiple publications resulting from a single study in the first table.
Every 3 months I need to create a report to QC studies added by coworkers so I run the following query (with some additional attributes removed for brevity). The where clause is a list of study IDs they provide me (often 15-20 different studies).
SELECT QAQC_Studies.StudiesID,
QAQC_Studies.NSL,
QAQC_Studies.StudyTitle,
QAQC_Studies.Abstract,
QAQC_Studies.StudyStatus
FROM QAQC_Studies
WHERE [QAQC_Studies].[StudiesID]=26806 or 26845
I'd like to add to that report a list of the publications associated with each study.
How do I write the Where clause in the second query to reference those studies indicated in the first query?
You can use a subquery. Something like:
SELECT [QAQC_Publications].[QAQC_Field]
FROM [QAQC_Publications]
WHERE [QAQC_Publications].[StudiesID] --or whichever field the two tables
--share for publication/study connection
IN (SELECT QAQC_Studies.StudiesID
FROM QAQC_Studies
WHERE [QAQC_Studies].[StudiesID]=26806 or 26845)

MS Access Text Search Box with referenced values

Lets assume I have 2 tables: Projects and Employees. Each project got one responsible employee that I chose as a Lookup Value from the Employee table.
Now I understand that Access saves the ID of the employee in the project table and that's good. However, now I want to create a search query to get all projects with e.g. Mike as responsible person.
This is my code:
SELECT projects.name, projects.responsible
FROM projects
WHERE projects.responsible = Forms!form_search!employee_name;
Now it works fine if I type in the Form the employee ID but I cannot remember all IDs. I want to be able to type in 'Mike' in the Form and the query delivers me still all of Mike's projects.
How can I achieve that?
I thought about something like:
WHERE (projects.responsible = (employees.ID WHERE employees.name = Forms...));
But this doesn't work...
You can use a dropdown list with 2 columns as a filter criteria.
To fill this list, you make a request on your employee table, hide the first column (0cm wide) and the second column would display the matching employee name but your SQL request still receive the ID as criteria.
You should NOT have to modify your SQL request.

Need query to return Null fields if no associated data in joined table

I'm trying to design a query in Access 2003 that returns information for a directory. One of the values I wish to include is contained in a second table, but that table doesn't have records for all the records I want.
I want a directory line for EACH MomID in table Registration, regardless of whether that MomID is referenced in table Kids. I can't just leave it out, because if there are children listed in Kids, that needs to be in the directory.
Currently, my query returns only those records where MomID is in both Registration and Kids. I'm filtering the data so that I only get records from Registration with the current YearStart field, so I can't make it an OR statement (even if I knew how). How do I get EVERY record in Registration which meets the YearStart criterion, and have the query return an empty field if the relevant MomID isn't present in Kids"
I could just go manually add MomID to Kids and leave the other fields blank, but that solution lacks elegance. I'm also not entirely sure that would work, since I'm running the data in Kids through two other queries to sort and concatenate before pulling it into the directory query. Plus, I'd like to retain the ability to include childless individuals in the directory if I ever want to expand the database to include the volunteers associated with the group.
What you're describing is a classic case of LEFT JOIN. This operator brings ALL records from the left part of the join even if there're no matches in the right part,
In your case it would be something like
SELECT * FROM Registration LEFT JOIN Kids ON Registration.MomID = Kids.MomID
WHERE Registration.YearStart = Year(Date())
Substitute * with only needed fields if you don't need all the fields from both tables.

Crystal Reports SQL Expression

I am having trouble figuring out how to pull a value from a secondary table, to use as selection criteria on a per-record basis.
I am working with Crystal Reports 2011 on Windows 7, over an ODBC connection to an Oracle 11g database.
I am creating an employee directory that utilizes information from two locations:
table: TEACHERS
view: PVSIS_CUSTOM_TEACHERS
The teachers table is set up with your predictable fields: id, lastname, firstname, telephone, address, city, state, zip, etc. etc. etc.
The view has the following fields available:
TEACHERID
FIELD_NAME
TEXT_VALUE
The database application I am using allows me to create "custom fields" that are related back to the main teachers table. In truth, the fields I am creating are actually stored in a separate table, but are then accessible through the PVSIS_CUSTOM_TEACHERS view. Since the database application allows for any number of "custom fields" to be created, the view can have any number of records in it that can be tied back to the records within the teachers table.
There are MANY custom fields that have been created, but for the purposes of my current project, only 3 of them matter:
empDirSupRecord
empDirSupPhone
empDirSupAddr
The view for my personal teacher record would look like this:
TeacherID Field_Name Text_Value
1 empDirSupRecord
1 empDirSupPhone 1
1 empDirSupAddr 1
1 AnotherField another_value
1 YetAnotherField yetanother_value
(This would indicate that I've asked for my phone and address to be suppressed, but would still want my name to be included in the directory)
These fields will each contain a '1' if the user has asked that their phone number, or address not be published, or if we need to suppress the entire record altogether.
When I first started my report, I pulled both the table and view into the database expert and linked them together with teachers.id = pvsis_custom_teachers.teacherid. However, this causes each teacher's name to print on the report once for every record with their teacher id in the view. Since that's not the behavior I want, I removed the view from the database expert, and tried using SQL Expression fields to retrieve the contents of the custom field. This is where I'm currently stuck. I would need to write the sql in a way that selects the correctly named field, for each of the teacher records as the record is being processed by the report.
Currently, my sql expressions statement is written as:
(SELECT text_value FROM pvsis_custom_teachers WHERE field_name = 'empDirSupRecord' AND teacherid = '1')
What I need to do is figure out how to get the report to intelligently select the record for teacherid = (whatever teacherid is currently being processed). I'm not sure if SQL Expression fields are the way to go to accomplish this, so am definitely open to alternate suggestions if my current approach will not work.
Thanks for taking a look. :-)
You're almost there with the SQL Expression. You can refer back to the main query with double quoted field names. So what you're looking for is:
case when "teacher"."id" is null then null
else (SELECT max(text_value)
FROM pvsis_custom_teachers
WHERE field_name = 'empDirSupRecord' AND teacherid = "teacher"."id")
end
Note that CR will likely complain without the null check and use of max(), since it wants to be sure that only a scalar will ever be returned.
The alternative, and likely less-performance-intensive way to do this, is to join the table and view like you first described. Then, you can group by {teacher.id} and keep track of each field name in the view via variables. This will require more work and more formulas, though. Something like this, for example:
//Place this formula in the Group Header
whileprintingrecords;
stringvar empDirSupRecord:="";
//Place this formula in the Details section
whileprintingrecords;
stringvar empDirSupRecord;
if {pvsis_custom_teachers.field_name} = 'empDirSupRecord'
then empDirSupRecord:={pvsis_custom_teachers.text_value}
//Place this formula in the Group Footer
whileprintingrecords;
stringvar empDirSupRecord;