moroz.dev

<< Back to index

小海豹都能懂的 inner join

假設我們要管理寵物資料庫。首先我們要確保電腦上有裝 PostgreSQL:

$ psql --version
psql (PostgreSQL) 12.4 (Ubuntu 12.4-0ubuntu0.20.04.1)

來建立新的資料庫並連接到新建立的資料庫:

createdb pets
psql pets

建立 humans 的資料表:

create type gender as enum('male', 'female', 'non_binary');

create table humans (
  id serial primary key, -- 主鍵
  name text not null,    -- 姓名
  gender gender not null
);

建立 pets 的資料表:

create table pets (
  id serial primary key, -- 主鍵
  name text not null,    -- 名字
  species text not null, -- 品種
  owner_id int not null, -- 一隻寵物 belongs to a human
  constraint fk_owner
    foreign key (owner_id)
      references humans (id)
);

create index pets_owner_id_idx on pets (owner_id);

新增幾個人:

insert into humans (name, gender)
values
('John Doe', 'male'),
('Jane Smith', 'female'),
('Marion Green', 'non_binary');

我們可以檢查 humans 資料表中的資料:

select * from humans;

然後新增一些寵物:

insert into pets (name, species, owner_id)
values
('Rex', 'Canis lupus familiaris', 1),
('Caesar', 'Canis lupus familiaris', 1),
('Simba', 'Panthera leo', 2);

要是我們知道 John Doe 的 ID,我們很容易查到他的寵物有哪些:

select * from pets where owner_id = 1;

然而,我們可能不知道 Jane Smith 的 ID,反而我們知道她的名字。在這種情況下,我們就是要用 INNER JOIN:

select * from pets
inner join humans on humans.id = pets.owner_id
where humans.name = 'Jane Smith';

其實呢,我們並沒有必要寫得這麼冗長,因為 JOIN 預設就是 INNER JOIN:

select * from pets
join humans on humans.id = pets.owner_id
where humans.name = 'Jane Smith';

另外,我們可以為資料表取比較簡短的名稱,比如 humans 可以縮寫成 h,而 pets 可寫為 p

select * from pets AS p -- AS 可以省略
join humans AS h on h.id = p.owner_id
where h.name = 'Jane Smith';