sql >> Database >  >> RDS >> PostgreSQL

Hoe maak je een Postgres-tabel met een unieke gecombineerde primaire sleutel?

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.



  1. LIKE vs BEVAT op SQL Server

  2. Een kolom toevoegen die een aaneenschakeling van twee andere Varchar-kolommen vertegenwoordigt

  3. Fout:PLS-00428:er wordt een into-clausule verwacht in deze select-instructie

  4. Hoe doe je mee aan dezelfde tafel, twee keer, in mysql?