Buat indeks unik:
CREATE UNIQUE INDEX matches_uni_idx ON matches
(greatest(winner, loser), least(winner, loser));
Tidak boleh UNIQUE
atau PRIMARY KEY
kendala, karena itu hanya bekerja dengan kolom, bukan ekspresi.
Anda dapat menambahkan serial
kolom untuk berfungsi sebagai PK, tetapi hanya dengan dua kolom bilangan bulat, PK asli Anda juga sangat efisien (lihat komentar). Dan itu membuat kedua kolom NOT NULL
secara otomatis. (Jika tidak, tambahkan NOT NULL
kendala.)
Anda juga dapat menambahkan CHECK
batasan untuk mengesampingkan pemain yang bermain melawan diri mereka sendiri:
CHECK (winner <> loser)
Petunjuk:Untuk mencari sepasang ID (di mana Anda tidak tahu siapa yang menang), buat ekspresi yang sama ke dalam kueri Anda, dan indeks akan digunakan:
SELECT * FROM matches
WHERE greatest(winner, loser) = 3 -- the greater value, obviously
AND least(winner, loser) = 1;
Jika Anda berurusan dengan parameter yang tidak diketahui dan Anda tidak tahu mana yang lebih baik sebelumnya:
WITH input AS (SELECT $id1 AS _id1, $id2 AS _id2) -- input once
SELECT * FROM matches, input
WHERE greatest(winner, loser) = greatest(_id1, _id2)
AND least(winner, loser) = least(_id1, _id2);
Pembungkus CTE hanya untuk kemudahan memasukkan parameter sekali saja dan tidak diperlukan dalam beberapa konteks.