I am putting together an MS Access database of our contacts for bidding purposes. I am at the point in the build where I would like to expand and display details of a company when you click a button. I have programmed the button to run my query and display the data on a form. The issue I am running into is: my data is being duplicated. For example:
I have a company (tbl_Company)
That company has 3 contacts (tbl_Contacts)
That company also has 2 licenses it holds (tbl_CoLic)
My query output is 6 rows of data, each contact with each license.
My end goal is to display on a form each company with all of their details, without duplicating other information. I have a total of 6 tables with different company details, each of those 6 tables can have one or more records associated with each company.
I can run separate queries to populate listboxes for each detail, but that seems cumbersome. Is there a better way? Please note this is all being done in MS Access, not SQL Server. Here is my query now:
SELECT tbl_Company.[Company Name], tbl_Contact.[First Name], tbl_Contact.[Last Name], tbl_CoLic.[License Number], tbl_CoLic.[License Code], tbl_CoLic.[Primary License], tbl_CoWA.County, tbl_CoPS.[Project Size], tbl_CoRef.District, tbl_CoRat.Rating, tbl_CoRat.Notes
FROM (((((tbl_Company INNER JOIN tbl_CoPS ON tbl_Company.[Company ID] = tbl_CoPS.[Company ID]) INNER JOIN tbl_CoRat ON tbl_Company.[Company ID] = tbl_CoRat.[Company ID]) INNER JOIN tbl_CoRef ON tbl_Company.[Company ID] = tbl_CoRef.[Company ID]) INNER JOIN tbl_CoLic ON tbl_Company.[Company ID] = tbl_CoLic.[Company ID]) INNER JOIN tbl_CoWA ON tbl_Company.[Company ID] = tbl_CoWA.[Company ID]) INNER JOIN tbl_Contact ON tbl_Company.[Company ID] = tbl_Contact.[Company ID]
WHERE (((tbl_Company.[Company ID])=[TempVars]![Details]));
Screenshot of Sample Data
Access expects forms and reports to have one record source. If you have a query or table with all the information your form needs you can just click it and access will build and manage a default form/report based on that one record source. So An access friendly approach is to give any form/report a table with everything it needs. So replicating your Database with some random suggestions and one important change -deleting the extra company name columns.
We can replicate your problem:
SELECT tbl_Company.CompanyName, tbl_Contact.FirstName, tbl_Contact.LastName, tbl_Colic.LicenseNumber, tbl_Colic.LicenseCode, tbl_Colic.PrimaryLicense, tbl_CoWA.County, tbl_CoWA.District, CompanyProjectSizes.ProjectSize, CompanyRatings.Rating, CompanyRatings.Notes
FROM ((((tbl_Company INNER JOIN tbl_Colic ON tbl_Company.CompanyID = tbl_Colic.CompanyID) INNER JOIN tbl_Contact ON tbl_Company.CompanyID = tbl_Contact.CompanyID) INNER JOIN tbl_CoWA ON tbl_Company.CompanyID = tbl_CoWA.CompanyID) INNER JOIN CompanyProjectSizes ON tbl_Company.CompanyID = CompanyProjectSizes.CompanyID) INNER JOIN CompanyRatings ON tbl_Company.CompanyID = CompanyRatings.CompanyID;
What's going on is When we combine the multiple tables into 1 we run into a problem because we have 2 license codes and each license code gets its own row. (rows in the combined table with any missing data are removed when inner joins are used. The reason we see anything is the company id for Rebel Plumbing has been added to all the formerly empty tables) The First part of your solution which sets up the next problem is to use a totals query.
SELECT tbl_Company.CompanyName, tbl_Contact.FirstName, tbl_Contact.LastName, First(tbl_Colic.LicenseNumber) AS FirstOfLicenseNumber, First(tbl_Colic.LicenseCode) AS FirstOfLicenseCode, First(tbl_Colic.PrimaryLicense) AS FirstOfPrimaryLicense, First(tbl_CoWA.County) AS FirstOfCounty, First(tbl_CoWA.District) AS FirstOfDistrict, First(CompanyRatings.Rating) AS FirstOfRating, First(CompanyRatings.Notes) AS FirstOfNotes
FROM ((((tbl_Company INNER JOIN CompanyProjectSizes ON tbl_Company.CompanyID = CompanyProjectSizes.CompanyID) INNER JOIN CompanyRatings ON tbl_Company.CompanyID = CompanyRatings.CompanyID) INNER JOIN tbl_Colic ON tbl_Company.CompanyID = tbl_Colic.CompanyID) INNER JOIN tbl_Contact ON tbl_Company.CompanyID = tbl_Contact.CompanyID) INNER JOIN tbl_CoWA ON tbl_Company.CompanyID = tbl_CoWA.CompanyID
GROUP BY tbl_Company.CompanyName, tbl_Contact.FirstName, tbl_Contact.LastName;
Now that you have the desired record source it works great in reports. However in this case When you create a form from your new record source the form quietly fails to update and edit!
What is going on is Access doesn't know how to change the tables in response to changes in the form. Most of the problem here is the total query we used. Here is a link describing when you can base a form on a query:
https://support.microsoft.com/en-us/office/use-a-query-as-the-record-source-for-a-form-or-report-e54251f3-57ca-4a7d-8e77-e498966cd41b
At this point There is not enough detail in the question to be specific about what to do. You will have to divide data entry into at least two parts in most cases as we can't put all the information into one access friendly record source. What parts will depend on user preference and how the rest of the data is structured. For the data provided I took the base tables in a form-subforms approach using the company table as the record source for the form and the contact and license tables as the subforms:
Related
Good afternoon,
I am creating a database for handling safety at my workplace.
I want to create a system where the user can raise a toolbox talk and through filters produce a list of employees who need to participate because they either belong to a certain department, certain competency or both.
To set the scene, an employee can be assigned multiple departments and multiple competencies in which case my select query: Query:ToolboxTalk works fine.
However there are occasions where an employee will be assigned to a department but maybe no competency. When this happens, my query does not return that employee because of the null value.
My question is this:
How can I make my query include null values or should I be going about this a different way?
Please see screenshot of my query in design view and SQL below:
SELECT tblEmployees.EmployeeID, IIf(IsNull([LastName]),IIf(IsNull([FirstName]),[FirstName]),IIf(IsNull([FirstName]),[LastName],[FirstName] & " " & [LastName])) AS [Employee Name], tblEmployees.Gender, tblDepartments.DepartmentID, tblDepartments.Department, tblCompetencies.CompetencyID, tblCompetencies.CompetencyDescription, tblEmployeesDepartments.EmployeesDepartmentID, tblEmployeesCompetencies.EmployeeCompetencyID
FROM (tblEmployees INNER JOIN (tblCompetencies INNER JOIN tblEmployeesCompetencies ON tblCompetencies.CompetencyID = tblEmployeesCompetencies.CompetencyID) ON tblEmployees.EmployeeID = tblEmployeesCompetencies.EmployeeID) INNER JOIN (tblDepartments INNER JOIN tblEmployeesDepartments ON tblDepartments.DepartmentID = tblEmployeesDepartments.DepartmentID) ON tblEmployees.EmployeeID = tblEmployeesDepartments.EmployeeID
WHERE (((tblEmployees.EmploymentStatus)="Active"));
Query-Design View Image
If there is any info I have neglected to include, please let me know and Ill endeavour to add it.
Thank you in advance!
Solution was to adjust query to left join with normalised table structure.
Refer picture and sql.
Query design view
Query SQL view
I am trying to create a process which logs historic subscription errors into a new table.
I've tried to do this by using the data within ExecutionLogStorage, I can't however see how this data relates to a specific SubscriptionID. I can join it to ReportID but as I have multiple subscriptions per report this doesn't achieve what I need.
I have tried googling various scripts, none actually link directly to SubscriptionID.
I need to be able to record a log of successful and unsuccessful executions of subscriptions throughout the day, which will then be inserted into a new table via a SQL Server Agent Job.
Run the following query :
SELECT
sj.[name] AS [Job Name],
rs.SubscriptionID,
c.[Name] AS [Report Name],
c.[Path],
su.Description,
su.EventType,
su.LastStatus,
su.LastRunTime
FROM msdb..sysjobs AS sj
INNER JOIN ReportServer..ReportSchedule AS rs
ON sj.[name] = CAST(rs.ScheduleID AS NVARCHAR(128))
INNER JOIN ReportServer..Subscriptions AS su
ON rs.SubscriptionID = su.SubscriptionID
INNER JOIN ReportServer..[Catalog] c
ON su.Report_OID = c.ItemID
This should give you a list of all reports with subscriptions and it's history.
You should be able to base this as a guide to do what ever else you need to do.
I have two data sources, one that tracks products and one that tracks financial information. The two do not have a common field, but they both have a common field with our billing system. I want to use our billing system data as a bridge table between my two sources so that I can connect product data to financial data in one analysis without having to do a messy and slow blend in our viz tool (for example – using case logic to make product.client = finance.account…inconsistent naming conventions are the worst). I am basically using billing as a lookup table to first join product to billing and then join finance to my new join…I think.
I want to create three mysql tables with fields along the lines of the lettered items.
1. Product
a. client
b. prod_id
c. size
d. metric
2. Finance
a. account
b. fine_id
c. amount
d. country
3. Billing
a. account
b. prod_id
c. fine_id
I am using billing as a lookup table to first join product to billing so that I can get all my product fields plus account and fine_id. I then want to join finance to that first join. I can make it work in excel, but the scale of data we are working with once (if) this tool goes live is too big for excel, thus the need for MySQL. Am I correct that I can achieve this type of join on a join w/ MySQL? I would really appreciate any syntax guidance on joining my finance table to the join below. Thanks!
Edit to post - syntax for joining, what is the proper order of my joins? the error that I get is simply that there is an error with my syntax.I am using the below. I have reordered it a few times but I am still missing some conceptual piece of how to do this. I want to 1. join product to billing (returning rows even where there isn't a match) 2. join finance to the product/billing outer join so that I can see my product and finance data in the same table. thanks for all the help!
select *
from
(select *
from
(select * from
lookup.product) as product_join
left outer join
(select *
from lookup.billing) as billing_join
on product_join.product_id = billing_join.product_id) as left # left join of billing to product
left outer join
(select *
from left) as left_join
left outer join
(select * from lookup.finance) as finance_join
on left.finance_id = financef_join.finance_id) # joining of finance data to the left join of my product/billing
Your task/question: "I want to create three mysql tables
with fields along the lines of the
lettered items.
Product a. client b. prod_id c. size d. metric
Finance a. account b. fine_id c. amount d. country
Billing a. account b. prod_id c. fine_id
I am using billing as a lookup table to first join product to billing so that I can get all my product fields plus account and fine_id. I then ..."
That's possible and easy with a join:
SELECT * From product, billing, finance
WHERE billing.account = finance.account
AND billing.fine_id = finance.fine_id
AND billing.prod_id = product.prod_id
On respect of your comment, you can use the left outer join like this, if a correspondent billing data does not exist and you want all products in the results:
SELECT * from product
LEFT outer join billing
ON product.prod_id = billing.prod_id
LEFT outer join finance
ON billing.account = finance.account
AND billing.fine_id = finance.fine_id;
You don't have to put another "select *" around a join. You can just join the tables together like this.
I'm having an issue with a mysql query for a search screen at work. I've got the query working using the code I'll post below, but I'm suspicious there is a better way to do it. Mysql are pretty newbie really, I just figure it out as I go along, or try to.
Here is the concept of the database:
There is an Entity, Address, Contact, Client, Group and Facility table involved in my query.
Each Client, Group and Facility is an "Entity" for lack of a better word. Each Entity has it's own Entity ID in the Entity table.
The Entity table houses an address record id and a contact record id.
On the facility search screen, if a user searches a phone number I want to search through the client and group records as well as the facility records. And then return any matching facility information as I normally would.
Here's what I've got so far(I'm doing nothing for address outside of facility records just yet and I've hardcoded some things for the sake of explaining myself):
SELECT facility.FacilityID, facility.Name, contact.PhoneNumber, addy.State addy.ZipCode, facility.ProductionFacilityID,
facility.ProductionEntityID
FROM Facility facility
INNER JOIN ClientGroup cg ON facility.GroupID = cg.GroupID
INNER JOIN Client c ON cg.ClientID = c.ClientID
INNER JOIN Entity e ON facility.FacilityID = e.EntityID
INNER JOIN Entity eg ON cg.GroupID = eg.EntityID
INNER JOIN Entity ec ON c.ClientID = ec.EntityID
INNER JOIN Contact contact ON e.BillingContactID = contact.ContactID
INNER JOIN Contact contactg ON eg.BillingContactID = contactg.ContactID
INNER JOIN Contact cc ON ec.BillingContactID = cc.ContactID
INNER JOIN Address addy ON addy.AddressID = e.PhysicalAddressID
WHERE (facility.FacilityID like '%$searchfor%'
OR contactg.PhoneNumber like '%$searchfor%'
OR cc.PhoneNumber like '%$searchfor%')
AND facility.IsRowActive=1
ORDER BY $searchtype";
Thanks in advance for the help!
Yes, the better way to do this for maintenance purposes is to create a view of only the inner joins and querying the view. Remember in terms of performance there would be little by way of improvement but maintenance of the code would become much easier.
Given your purpose the inner joins are not entirely avoidable unless you decide to change the structure of the tables
I am writing a query for a health organization. The query is to pull patient data, where an encounter/appointment was completed but a chart note was not generated. I have the query pulling patients and their appointments; is there a way to basically say "only show the patients where 'master_im' document was not generated"?
I am using Microsoft SQL Server Management Studio.
Without seeing your table structures, etc. your could do a check to see if the master_im IS NULL.
SELECT *
FROM yourTable
WHERE appointment = 'completed'
AND master_im IS NULL
I would advise posting some additional details on your tables.
If the data is stored in separate tables, then you will want to JOIN the tables together to get the results you want.
EDIT #1 based on your comment you could do something like this:
select *
from person p
inner join appointments a
on p.enc_id = a.encid
left join patient_documents pd
on p.enc_id = pd.enc_id
where a.status = 'completed'
and pd.document_desc != 'master_im'