Maak een unieke index:
CREATE UNIQUE INDEX matches_uni_idx ON matches
(greatest(winner, loser), least(winner, loser));
Kan geen UNIQUE
zijn of PRIMARY KEY
beperking, aangezien deze alleen werken met kolommen, niet met uitdrukkingen.
U kunt een serial
. toevoegen kolom om als PK te dienen, maar met slechts twee integer-kolommen is uw originele PK ook zeer efficiënt (zie opmerkingen). En het maakt beide kolommen NOT NULL
automatisch. (Anders, voeg NOT NULL
toe beperkingen.)
U kunt ook een CHECK
. toevoegen beperking om uit te sluiten dat spelers tegen zichzelf spelen:
CHECK (winner <> loser)
Hint:als u naar een paar ID's wilt zoeken (waarvan u niet weet wie er heeft gewonnen), bouwt u dezelfde uitdrukkingen in uw zoekopdracht in en de index wordt gebruikt:
SELECT * FROM matches
WHERE greatest(winner, loser) = 3 -- the greater value, obviously
AND least(winner, loser) = 1;
Als je te maken hebt met onbekende parameters en je weet van tevoren niet welke groter is:
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);
De CTE-wrapper is alleen voor het gemak om parameters eenmalig in te voeren en is in sommige contexten niet nodig.