单表查询只能看一本账册。
而真实业务里,你经常要把“市民”“户号”“行政区”对起来看。这时就要用 JOIN。
查某市民属于哪个户、哪个区:
SELECT
c.citizen_id,
c.full_name,
h.household_no,
d.district_name
FROM citizens AS c
JOIN households AS h
ON h.household_id = c.household_id
JOIN districts AS d
ON d.district_id = h.district_id
WHERE c.status = 'active';这里不是“把表机械拼接”,而是:
拿着一个账册里的编号,去另一册里对号。
常见 JOIN 可以这样记:
INNER JOIN:两边能对上的才保留LEFT JOIN:左边全保留,右边对不上就补NULL
比如,想查所有市民及最近一次迁户记录,没有迁户历史的人也要显示出来:
SELECT
c.full_name,
m.reason,
m.moved_at
FROM citizens AS c
LEFT JOIN move_logs AS m
ON m.citizen_id = c.citizen_id
WHERE c.status = 'active';LEFT JOIN 的经典坑是:把右表过滤条件写进 WHERE,结果把左边“没匹配上的行”也过滤掉了。
例如下面这句就很危险:
SELECT c.full_name, m.reason
FROM citizens AS c
LEFT JOIN move_logs AS m
ON m.citizen_id = c.citizen_id
WHERE m.reason = '升学迁入';它常常会让结果看起来像 INNER JOIN。
如果你真想保留左边所有市民,右边只匹配某类记录,通常应该把条件放进 ON:
SELECT c.full_name, m.reason
FROM citizens AS c
LEFT JOIN move_logs AS m
ON m.citizen_id = c.citizen_id
AND m.reason = '升学迁入';