Access Database Table setup - ms-access

I am setting up a program for contacts. I want to keep track of the contact and their email and phone number and what company they work for if we have that readily available. I will not always have the company they work for though so I set it up line this:
tblContacts
ContactID
ContactName
ContactPhoneNumber
tblCompanies
CompanyID
CompanyName
tblContactsInCompanies
CICID
CompanyID
ContactID
I did the ContactsInCompanies because not all of the contacts would have a company assigned. Now I am trying to get all of the contacts with the company name they are in if it is available and I cannot get the Joins to work.
Since I am having so much trouble, I thought I would ask if that is the way it should be set up or not (would anyone recommend a different setup). If that is OK, how would I get the list of all contacts and the company name if it is assigned? I have been trying to LEFT JOIN and INNER JOIN but I just get an error unless all are INNER JOIN but then it doesn't show contacts that do not have a company.

I was finally able to get a combination that worked.
SELECT Contacts.*, Companies.CompanyName
FROM Companies RIGHT JOIN (Contacts LEFT JOIN ContactsInCompanies ON
Contacts.ContactID = ContactsInCompanies.ContactID) ON
Companies.CompanyID = ContactsInCompanies.CompanyID;
These always seem to confuse me. :( Thanks for looking.

Related

mysql join and count field values

Very new to using mysql, so please excuse me if this question is really elementary. It would be great if someone could at least suggest what topic I should be researching.
I have 3 tables, user, computer, component. (this is just an example).
user computer component
---- ------- ----
id id id
firstName user_id computer_id
lastName name componentName
type componentValue
A user may have multiple computers, which in turn may have multiple properties.
I am trying to write a query that can get all user ids who have all of their 'Macintosh' computers contain all 'ram' components with '16GB' values.
So far I am struggling with getting the counts right, but have written something like this:
select user.id from user
inner join computer on user.id=computer.user_id and computer.name='Macintosh'
inner join component on computer.id=component.computer_id and component.componentName='ram'
having count(component.propertyName='ram')=count(component.propertyValue='16GB');
Thanks in advance for any constructive feedback.
You could filter for componentValue = '16GB'
select user.id
from user
inner join computer on user.id=computer.user_id and computer.name='Macintosh'
inner join component on computer.id=component.computer_id
and component.componentName='ram'
and component.componentValue = '16GB'
and if you want only the use that have computer with only 16GB ram you could use
select user.id
from user
inner join computer on user.id=computer.user_id and computer.name='Macintosh'
and computer.id not (
select component.computer_id
from component
where component.componentName='ram'
and component.componentValue <> '16GB')

Selecting data from joined tables based on one distinct field but returning all other columns

I have looked through many previous questions but can't seem to find one that matches my query?
My current site has customer details stored across different tables within the database.
I have managed to join the tables based on Firstname and Lastname with:
Select *
FROM ps_customer
INNER JOIN ps_address
ON ps_address.Firstname = ps_customer.Firstname AND
ps_address.Lastname = ps_customer.Lastname
However, the results contain duplicated email addresses for the same customers. What I wanted was to do was return all columns from the joined tables but only for distinct/unique email address? is there a command that can do this?
ps I'm very new to sql, so apologies for nontechnical language
I wanted to do something like in this picture enter image description here
Use DISTINCT:
SELECT DISTINCT
pc.ID,
pc.Firstname,
pc.Lastname,
pa.Address1,
pa.Address2,
pa.Zip,
pc.email
FROM ps_customer pc
INNER JOIN ps_address pa
ON pa.Firstname = pc.Firstname AND
pa.Lastname = pc.Lastname;
I don't know exactly which columns you want to select, but the above pattern should be one way to go here.

Get two names by ID from another table

For a hockey website, I would like to display past results from the home team and of course display the name of the away team. I could make it almost to the end, but I can't the away team name to show up. I receive all needed results from the RESULTS table. In there I have the home_team_id and the away_team_id, which I need to connect to the TEAM table in order to show the team name. I could do this with the home team but have no idea how to get the away team names of those found in there.
results table
teams table
This is what shows me everything, but no away team name:
SELECT results.home_team_id
, results.away_team_id
, results.ft_score
, teams.name
FROM results
LEFT
JOIN teams
ON results.home_team_id = teams.team_id
WHERE results.home_team_id = '$hteam‘"
I have check other post with similar problems/question, but they did not help me. Sorry.
Help would be great!
Thank you very much!
You need to join the teams table twice with different alias names
SELECT results.home_team_id, results.away_team_id,
results.ft_score,
thome.name as home_name, taway.name as away_name
FROM results
LEFT JOIN teams thome ON results.home_team_id = thome.team_id
LEFT JOIN teams taway ON results.away_team_id = taway.team_id
WHERE results.home_team_id = '$hteam'

How to create an Outer Join on 4 Tables to get all values Plus Count of 1 field

I have 4 tables which need to be joined. They are:
Contractors
Crews
Skill_type
Location
I also need to be able to count the number of contractors in each crew.
I have created some SQL (MySql) which does the job nicely:
Select contractors.crew_id as contractors_crew_id,
auburntree.crews.crew_name, count(*) as members, skill_type.skill,
location.location_name
FROM contractors
JOIN auburntree.crews on contractors.crew_id=crews.id
JOIN skill_type on skill_type.skill_id = crews.skill_id
JOIN location on location.id = crews.location_id
GROUP BY contractors.crew_id ;
The contractors table contains a foreign key reference to which crew they are assigned to. Hence the column "contractors_crew_id"
I get a nice result, as you can see in this screen capture image:
https://drive.google.com/file/d/0B5elaUk7GlRoS0JWblE3ZzFXY0E/view?usp=sharing
Problem Defined:
I need to define an empty crew first before I add contractors/members. I will give it a name, a skill and a location. I might define an empty crew several days in advance. Currently an empty crew does not show up in my results.
I want to see:
contractors_crew_id = Null, crew_name, skill_type, Location, members 0
I have tried using RIGHT OUTER JOIN on my tables and I still do not see empty crew. LEFT OUTER JOIN does not work either.
contractors_crew_id will be Null at that point, as no contractors have been assigned yet.
I Hope this makes, sense - sorry it is a bit long and complicated. I have tried really hard to explain in.
Many Thanks !!
Because you are actually focussing on information about crews, and not contractors, I would suggest to start by querying the crews table (in the FROM part of your query) and then join the other tables.
Using a LEFT JOIN on the contractors table should then give you the desired result. Since crews is now the "left" table in the query, the result will include all rows from crews, even when there is no corresponding contractor. This answer explains it very well.
This query works for me on test tables based on your examples:
SELECT
contractors.crew,
crews.crew,
COUNT(contractors.id) as members,
skills.skill,
locations.location
FROM crews
JOIN skills ON crews.skill = skills.id
JOIN locations ON crews.location = locations.id
LEFT JOIN contractors ON contractors.crew = crews.id
GROUP BY contractors.crew, crews.id;
To see for yourself, try this SQL Fiddle.
Try this, instead:
Select contractors.crew_id as contractors_crew_id, crews.crew_name, count(*) as members, skill_type.skill, location.location_name
FROM crews
LEFT OUTER JOIN contractors on contractors.crew_id=crews.id
LEFT OUTER JOIN skill_type on skill_type.skill_id = crews.skill_id
LEFT OUTER JOIN location on location.id = crews.location_id
GROUP BY contractors.crew_id ;
That should pull all crews, regardless of whether or not they have contractors assigned. The way you wrote your original query starts by looking at your contractors and then pulling in any crews they might be assigned to. Crews is clearly your focal table here, so you should be joining the rest of your tables to it, rather than to the contractors table.

mysql inner join same table and same column multiple times from multiple tables

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