Vytvořte jedinečný index:
CREATE UNIQUE INDEX matches_uni_idx ON matches
(greatest(winner, loser), least(winner, loser));
Nemůže být UNIQUE
nebo PRIMARY KEY
omezení, protože fungují pouze se sloupci, nikoli s výrazy.
Můžete přidat serial
slouží jako PK, ale s pouhými dvěma celočíselnými sloupci je váš původní PK také velmi efektivní (viz komentáře). A to dělá oba sloupce NOT NULL
automaticky. (V opačném případě přidejte NOT NULL
omezení.)
Můžete také přidat CHECK
omezení k vyloučení hráčů, kteří hrají sami proti sobě:
CHECK (winner <> loser)
Tip:Chcete-li vyhledat pár ID (kde nevíte, kdo vyhrál), zabudujte do dotazu stejné výrazy a použije se index:
SELECT * FROM matches
WHERE greatest(winner, loser) = 3 -- the greater value, obviously
AND least(winner, loser) = 1;
Pokud se zabýváte neznámými parametry a předem nevíte, který je větší:
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);
CTE wrapper slouží pouze pro usnadnění zadání parametrů pouze jednou a v některých kontextech to není nutné.