Skapa ett unikt index:
CREATE UNIQUE INDEX matches_uni_idx ON matches
(greatest(winner, loser), least(winner, loser));
Kan inte vara en UNIQUE
eller PRIMARY KEY
begränsning, eftersom de bara fungerar med kolumner, inte uttryck.
Du kan lägga till en serial
kolumn för att fungera som PK, men med bara två heltalskolumner är din ursprungliga PK också mycket effektiv (se kommentarer). Och det gör båda kolumnerna NOT NULL
automatiskt. (Annars, lägg till NOT NULL
begränsningar.)
Du kan också lägga till en CHECK
begränsning för att utesluta att spelare spelar mot sig själva:
CHECK (winner <> loser)
Tips:För att söka efter ett par ID:n (där du inte vet vem som vann), bygg in samma uttryck i din fråga, så kommer indexet att användas:
SELECT * FROM matches
WHERE greatest(winner, loser) = 3 -- the greater value, obviously
AND least(winner, loser) = 1;
Om du hanterar okända parametrar och du inte vet vilken som är störst i förväg:
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-omslaget är bara för bekvämlighets skull att ange parametrar en gång och inte nödvändigt i vissa sammanhang.