MySQL joining data from 2 tables based on foreign key in a third, without
duplicates or group by
I have three tables that look like this:
People:
+------------+-------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra
|
+------------+-------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL |
auto_increment |
| fname | varchar(32) | NO | | NULL |
|
| lname | varchar(32) | NO | | NULL |
|
| dob | date | NO | | 0000-00-00 |
|
| license_no | varchar(24) | NO | | NULL |
|
| date_added | timestamp | NO | | CURRENT_TIMESTAMP |
|
| status | varchar(8) | NO | | Allow |
|
+------------+-------------+------+-----+-------------------+----------------+
Units:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| number | varchar(3) | NO | | NULL | |
| resident | int(11) | NO | MUL | NULL | |
| type | varchar(16) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
Visits:
+----------+-----------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-----------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| vis_id | int(11) | NO | MUL | NULL | |
| unit | int(11) | NO | MUL | NULL | |
| time_in | timestamp | NO | | CURRENT_TIMESTAMP | |
| time_out | timestamp | NO | | 0000-00-00 00:00:00 | |
+----------+-----------+------+-----+---------------------+----------------+
There are multiple foreign keys linking these tables:
units.resident -> people.id
visits.unit -> units.id
visits.vis_id -> people.id
I am able to run this query to find all residents ie - everyone from
people that are referenced by the units.resident foreign key:
SELECT concat(p.lname, ', ', p.fname) as 'Resident', p.dob as 'Birthday',
u.number as 'Unit #'
from people p, units u
where p.id = u.resident
order by u.number
It returns the results I want... However, it'd be useful to do the
opposite of this to find all the people who are not residents ie- everyone
from people who aren't referenced by the units.resident foreign key.
I've tried many different queries, most notably some inner and left joins,
but I'm getting waaaaay too many duplicate entries (from what I've read
here, this is normal). The only thing I've found that works is using a
group by license_no, because as of now the "residents" don't have this
information, like this:
SELECT p.id, concat(p.lname, ', ', p.fname) as 'Visitor',
p.license_no as 'License', u.number from people p
left join units u on u.number <> p.id
group by p.license_no order by p.id;
This works for all but one resident, who's u.number is displayed on ALL
results. The residents will soon have license_no entries, and I can't have
that one odd entry in the returned results all the time, so this query
won't work as a long-term solution.
How can I structure a query without a group by that will return the
results I want?
No comments:
Post a Comment