0
votes

Assurez-vous que pas deux lignes contiennent des valeurs identiques dans PostgreSQL

J'ai une table et je veux m'assurer que pas deux rangées ne peuvent être semblables.

Donc, par exemple, cette table serait valide: xxx

Mais cette table ne serait pas: xxx

c'est parce que la dernière table a deux instances de 1 | Thinkjet .

donc, user_id peut être répété (c'est-à-dire 1 ) et l'imprimante peut être répété (c.-à-d. laserwriter ) mais une fois un disque comme 1 | Thinkjet est entré une fois que la combinaison ne peut pas être entrée à nouveau.

Comment puis-je empêcher de telles occurrences dans une table PostgreSQL 11.5?

J'essaierais d'expérimenter un code SQL mais Hélas Je suis toujours nouveau sur la question.

Veuillez noter que c'est pour insérer des données dans la table, pas Sélectionnez ING IT. < / strong> comme une contrainte IIRC.

merci


0 commentaires

4 Réponses :


0
votes

Vous pouvez utiliser distinct. Par exemple: xxx

c'est tout. J'espère que cela aide!


4 commentaires

Merci, mais cela seulement montre distincts distincts, je peux toujours insérer des enregistrements identiques dans la table, ce que je ne veux pas pouvoir faire.


Oh pardon. J'ai compris. Vous devez vérifier votre colonne d'imprimante comme unique dans la base de données. De cette façon, vous ne pourrez pas insérer un enregistrement en double.


Eh bien, je pourrais faire cela, mais j'aimerais avoir des entrées d'imprimante en double et dupliquer User_id Entre, mais je ne veux pas avoir le même enregistrement user_id / imprimante deux fois. J'ai mis à jour mon exemple pour clarifier.


Je suis désolé que l'anglais n'est pas ma langue principale. J'essaierai. Prenons une nouvelle table. user_id = 1 et imprimante = thinkjet dans la première ligne. Si vous essayez à nouveau ( 1 et thinkjet ) il fonctionnera normalement. Je le veux, il est donc possible d'erreur si vous essayez à nouveau d'ajouter cette combinaison. Si vous ajoutez user_id = 1 Imprimante > = laserwriter , cela fonctionne depuis que cette combinaison n'est pas déjà utilisée. Si vous ajoutez user_id = 2 et imprimante = thinkjet qui fonctionnera car cette combinaison n'est pas déjà utilisée non plus. J'espère que ça aide.



1
votes

Voici votre script

ALTER TABLE tableA ADD CONSTRAINT some_constraint PRIMARY KEY(user_id,printer);

INSERT INTO tableA(user_id, printer)
VALUES
   (
      1,
      'LaserWriter'
   ) 
ON CONFLICT (user_id, printer) 
DO NOTHING;


5 commentaires

Merci, mais je reçois une erreur : il n'y a pas de contrainte unique ou d'exclusion correspondant à la spécification de conflit


modifier votre table d'abord.


Ne pas sembler impoli, mais si j'ai déjà fait une contrainte pour rendre la colonne User_id et imprimante, la clé primaire Pourquoi dois-je ajouter le supplémentaire sur le conflit ... Ne faites rien; pièces?


On dirait que vous obtenez votre problème actuel. À l'avenir, vous pouvez trouver des situations où vous voulez une unicité ou une autre contrainte, sur autre chose qu'une clé primaire. Postgres a toutes sortes d'options à explorer, notamment chèque, uniques et des domaines. postgreSQL.org/docs/current/... < / a>


@MorRISDEORYX Oui, mais dans ce tableau, je ne le garderai plus que dans ces deux colonnes (toutes les autres contraintes sont toutes triées déjà). Je vois que cela soit utile dans d'autres tables / colonnes, cependant. Merci



0
votes

J'ai trouvé la réponse. Lors de la création du tableau, je devais spécifier les deux colonnes comme unique. Observez:

=# INSERT INTO foo VALUES (1, 'LaserWriter');
INSERT 0 1

=# INSERT INTO foo VALUES (4, 'LaserWriter');
INSERT 0 1

=# INSERT INTO foo VALUES (1, 'ThinkJet');
INSERT 0 1

=# INSERT INTO foo VALUES (2, 'DeskJet');
INSERT 0 1

=# INSERT INTO foo VALUES (1, 'ThinkJet');
ERROR:  duplicate key value violates unique constraint "foo_user_id_printer_key"
DETAIL:  Key (user_id, printer)=(1, ThinkJet) already exists.

=# SELECT * FROM foo;
 user_id |   printer   
---------+-------------
       1 | LaserWriter
       4 | LaserWriter
       1 | ThinkJet
       2 | DeskJet
(4 rows)


0 commentaires

0
votes

Vous avez besoin d'une série d'étapes (en supposant qu'il n'y ait pas de clé unique déjà attribuée).

  1. Ajoutez une colonne temporaire pour faire chaque rangée unique. LI>
  2. Attribuez une valeur aux nouvelles colonnes. LI>
  3. supprimer les doublons déjà existants. LI>
  4. Créez une clé unique ou primaire sur les colonnes composites. LI>
  5. Supprimer la colonne temporaire. LI> OL>
    alter table your_table add temp_unique integer unique;
    
    do $$
    declare
        row_num  integer = 1;
        c_assign cursor for
            select temp_unique 
              from your_table
               for update;
    begin 
        for rec in c_assign
        loop
           update your_table 
              set temp_unique = row_num
            where current of c_assign;
           row_num = row_num + 1;
        end loop; 
    end; 
    $$
    
    delete from your_table ytd
     where exists ( select 1
                      from your_table ytk
                     where ytd.user_id = ytk.user_id
                       and ytd.printer = ytk.printer
                       and ytd.temp_unique > ytk.temp_unique 
                  )  ; 
    
    alter table your_table add constraint id_prt_uk unique (user_id, printer);
    
    alter table your_table drop temp_unique;
    


1 commentaires

Cela fonctionne probablement, mais c'est bien sur ce que ma connaissance SQL est. * Dizzy * Merci pour l'aide, peu importe