0

我有三个看起来像这样的表:

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 |                |
+----------+-----------+------+-----+---------------------+----------------+

有多个外键链接这些表:

units.resident -> people.id

visits.unit    -> units.id

visits.vis_id  -> people.id

我可以运行这个查询来查找所有居民,即外键people引用的每个人:units.resident

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

它返回我想要的结果......但是,与此相反,找到所有不是居民的人(即外键people未引用的所有人)会很有用。units.resident

我尝试了许多不同的查询,最显着的是一些内连接和左连接,但是我得到了太多重复的条目(从我在这里读到的内容来看,这是正常的)。我发现唯一可行的是使用 a group by license_no,因为到目前为止“居民”没有这些信息,如下所示:

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;

这适用于除一位居民外的所有人,他的u.number信息显示在所有结果中。居民很快就会有license_no条目,而我不能一直在返回的结果中出现那个奇怪的条目,所以这个查询不会作为一个长期的解决方案。

如何构造一个没有返回group by我想要的结果的查询?

4

2 回答 2

2

这应该工作

SELECT 
 p.id
 , P.fname
 , P.lname
FROM
 people AS p
LEFT JOIN
 units AS u
ON
 p.id = u.resident 
WHERE
 u.resident IS NULL

额外提示。

餐桌人应该被称为人。你所说的 u.resident 是指一个人。所以它应该是单元表中的person_id ...

如果您的名称约定清晰易用,则更好的逻辑有助于更好地编写 SQL。

于 2013-08-15T19:28:25.010 回答
1

使用 NOT EXISTS 子句排除居民。

SELECT  P.id
        ,P.fname
        ,P.lname
        ,etc...
FROM    People P
WHERE NOT EXISTS (SELECT 1 FROM Units U WHERE U.resident = P.id)
于 2013-08-15T19:14:32.827 回答