I have the following tables:
companyContacts
addresses
states
phoneNumbers
And I need to do a LEFT JOIN on addresses, states, and phoneNumbers. I need to connect phoneNumbers and addresses with companyContacts, and need to connect states with addresses.
I can do a select like the following to grab everything. However, If someone has an address and not a phone number, it will not return a result. How do I make it so that both phoneNumbers and addresses are joined from companyContacts?
SELECT * FROM
companyContacts AS c
LEFT JOIN phoneNumbers AS p
ON c.entityID = p.entityID
LEFT JOIN addresses AS a
ON p.entityID = a.entityID
LEFT JOIN states AS s
ON a.stateID = s.id
It sounds like you want this:
SELECT *
FROM companyContacts AS c
LEFT JOIN phoneNumbers AS p
ON c.entityID = p.entityID
LEFT JOIN addresses AS a
ON c.entityID = a.entityID
LEFT JOIN states AS s
ON a.stateID = s.id
If you join on the companyContacts.entityId to both the phoneNumbers and addresses then you will return records even if there is not a phone number or address. The way you had it written the phone number needed to exist to return an address
Related
Let's say that I have two tables A and B where
A is table countries with columns id, name, created, modified
that contains a bunch of countries
And B is table users with columns id, first_name, last_name, email, country_id, created, modified
that contains a bunch of users linked to countries via foreign key country_id
What is the most efficient query to get all the countries that don't have a user with email address "myemail#test.com" associated to it?
I tried something like the following but that didn't work:
SELECT DISTINCT
c.*
FROM
countries c
LEFT JOIN
users u ON u.country_id = c.id
WHERE
u.email <> 'myemail#test.com'
Thanks for any help
NOTE I also tried putting the condition on the email column in the ON clause that didn't work either
A left join is fine, you just need to set it up correctly:
SELECT c.*
FROM countries c LEFT JOIN
users u
ON u.country_id = c.id AND u.email = 'myemail#test.com'
WHERE u.country_id IS NULL;
In terms of performance, this should be pretty similar to NOT EXISTS and NOT IN (although I do not recommend the latter because it has different behavior when there are NULL values).
When you say "that don't have a user with email address "myemail#test.com"",
do you mean no email address -or- not that exact email address?
Updated
Then this should do:
SELECT DISTINCT c.*
FROM countries c
LEFT JOIN users u ON u.country_id = c.id and u.email = 'myemail#test.com'
WHERE u.country_id is null
Which I believe is what Gordon already had.
Updated Again
In that case, try:
SELECT DISTINCT c.*
FROM countries c
INNER JOIN users u ON u.country_id = c.id and ISNULL(u.email, '') = ''
This looks for Null or Empty String email adresses all others are excluded from the join and therefore from the result set.
I hope this helps.
Let say that I have got three tables: account, contact and address. To account and contact I want to assign multiple addresses. Is it better to have two fields in address join_type and join_id and then for example running query:
SELECT a.*
FROM address a
INNER JOIN contact c ON c.id = a.join_id AND a.join_type = 'CONTACT';
and
SELECT a.*
FROM address a
INNER JOIN account ac ON ac.id = a.join_id AND a.join_type = 'ACCOUNT';
or have account_id and contact_id instead of join_type and join_id and running query:
SELECT a.*
FROM address a
INNER JOIN contact c ON c.id = a.contact_id;
and
SELECT a.*
FROM address a
INNER JOIN account ac ON ac.id = a.account_id;
or maybe even have got two seperate address tables for account and contact? The first option is the best for future if I would like e.g. have also addresses assigned to users.
SELECT a.*
FROM address a
INNER JOIN contact c ON c.id = a.contact_id;
The fact that you have multiple types of addresses should not cause any problem since the contact_id should always be unique.
I would also consider having another column in address with account_id and have another join like this:
SELECT a.*
FROM address a
INNER JOIN account a ON a.id = a.account_id;
I have three MySQL tables: 'people', 'people2id', 'places'. The first one stores information about people, where the 'places' table stores information about their addresses. The middle one, 'people2id', interconnects this two tables (could be that one person has two or more addresses).
Now I want to go to some person's profile and see his profile, but also his associated addresses. I created this query for that:
SELECT * FROM people p
JOIN people2id e ON p.peopleId = e.peopleId
JOIN places a ON a.peopleId = e.peopleId
WHERE p.peopleId = number
This works when the person has associated address(es), otherwise, it will fail. I do not understand if I should use any kind of JOIN or use UNION for this matter.
Change the JOIN to LEFT JOIN, i.e.
SELECT * FROM people p
LEFT JOIN people2id e ON p.peopleId = e.peopleId
LEFT JOIN places a ON a.peopleId = e.peopleId
WHERE p.peopleId = number
Using LEFT JOIN will include all the records from people, whether they contain associated records or not.
UNION is used for get same kind of informations from two different queries and return them as a single result set
JOIN is used for add columns and data to rows (not as simple but you can see it like this)
You should use LEFT JOIN.
SELECT * FROM people p
JOIN people2id e ON p.peopleId = e.peopleId
LEFT JOIN places a ON a.peopleId = e.peopleId
WHERE p.peopleId = number
I have this hierarchy in my database (from lowest to highest):
User => Dept => Area => Company
Now I need to make a table that shows all companies (some info about them taken directly from companies table) but the last column in the HTML table I want to be Number of users. I know I need to join the tables together and perhaps join table to itself, but how do I do this?
Each of these tables have a column linking to its parent table (except Company ofc).
JOIN the tables:
SELECT
c.companyId,
c.CompanyName,
IFNULL(COUNT(u.userID), 0) AS 'Number Of Users'
FROM Company AS c
LEFT JOIN Area AS a ON c.CompanyID = a.CompanyID
LEFT JOIN Dept AS d ON a.DeptId = d.DeptId
LEFT JOIN users AS u ON D.UserId = u.UserId
GROUP BY c.companyId,
c.CompanyName;
Note that: LEFT JOIN with IFNULL will give you those companies that has no matched rows in the other tables; with count zero in this case
i have a MySQL SELECT query which fetches data from 6 tables using Mysql JOIN. here is the MySQL query i am using.
SELECT
u.id,u.password,
u.registerDate,
u.lastVisitDate,
u.lastVisitIp,
u.activationString,
u.active,
u.block,
u.gender,
u.contact_id,
c.name,
c.email,
c.pPhone,
c.sPhone,
c.area_id,
a.name as areaName,
a.city_id,
ct.name as cityName,
ct.state_id,
s.name as stateName,
s.country_id,
cn.name as countryName
FROM users u
LEFT JOIN contacts c ON (u.contact_id = c.id)
LEFT JOIN areas a ON (c.area_id = a.id)
LEFT JOIN cities ct ON (a.city_id = ct.id)
LEFT JOIN states s ON (ct.state_id = s.id)
LEFT JOIN countries cn ON (s.country_id = c.id)
although query works perfectly fine it sometimes returns duplicate results if it finds any duplicate values when using LEFT JOIN. for example in contacts table there exist two rows with area id '2' which results in returning another duplicated row. how do i make a query to select only the required result without any duplicate row. is there any different type of MySQL Join i should be using?
thank you
UPDATE :
here is the contacts table, the column area_id may have several duplicate values.
ANSWER :
there was an error in my condition in last LEFT JOIN where i have used (s.country_id = c.id) instead it should be (s.country_id = cn.id) after splitting the query and testing individually i got to track the error. thank you for your response. it works perfectly fine now.
Duplicating the rows like you mentioned seems to indicate a data problem.
If users is your most granular table this shouldn't happen.
I'd guess, then, that it's possible for a single user to have multiple entries in contacts
You could use DISTINCT as mentioned by #dxprog but I think that GROUP BY is more appropriate here. GROUP BY whichever datapoint could potentially be duplicated....
After all, if a user has corresponding contact records, which one are you intending to JOIN to?
You must specify this if you want to remove "duplicates" because, as far as the RDBMS is concerned, the two rows matching
LEFT JOIN contacts c ON (u.contact_id = c.id)
Are, in fact, distinct already
I think a DISTINCT may be what you're looking for:
SELECT DISTINCT
u.id,u.password,
u.registerDate,
u.lastVisitDate,
u.lastVisitIp,
u.activationString,
u.active,
u.block,
u.gender,
u.contact_id,
c.name,
c.email,
c.pPhone,
c.sPhone,
c.area_id,
a.name as areaName,
a.city_id,
ct.name as cityName,
ct.state_id,
s.name as stateName,
s.country_id,
cn.name as countryName
FROM users u
LEFT JOIN contacts c ON (u.contact_id = c.id)
LEFT JOIN areas a ON (c.area_id = a.id)
LEFT JOIN cities ct ON (a.city_id = ct.id)
LEFT JOIN states s ON (ct.state_id = s.id)
LEFT JOIN countries cn ON (s.country_id = c.id)
This should only return rows where the user ID is distinct, though you may not get all the joined data you'd hoped for.