Pseudo Unique
9 Décembre 2016 , Rédigé par Pam007 Publié dans #Sql
Il arrive qu'une table, qui devrait être unique, ne le soit que très modérément...
Ceci pose des problèmes lors d'éventuelles jointures : les lignes se multiplient !
Dans d'autre configuration, une non-unicité peut se terminer en plantage de la requête.
create table pays (pays_id char (3), libelle varchar (99));
-- On a oublié la clé primaire... Et il y a des doublons sur le pays !
create table personne(
personne_id dec(3, 0) primary key generated always as identity,
nom varchar(50),
pays_naiss char(3));
select * from personne left join pays on pays_naiss = pays_id;
-- Lignes dupliquées par la jointure !
-- Comment riposter :
select personne_id, nom, pays_naiss, (select libelle from pays b where a.pays_naiss = b.pays_id fetch first row only) as libelle from personne a;
-- par une judicieuse sous-requête scalaire de type full select, les lignes en trop sont évitées grace à "fetch first row only".
with pays_unique ( pays_id, libelle) as
(select pays_id, (select libelle from pays b where a.pays_id = b.pays_id fetch first row only) from pays a group by pays_id)
select * from personne left join pays_unique on pays_naiss = pays_id;
-- autre possibilité, la table mal gaulée est raffinée dans une CTE, ce qui permet son utilisation dans le join qui suit.
create view pays_uv (pays_id, libelle) as
(select pays_id, (select libelle from pays b where a.pays_id = b.pays_id fetch first row only) from pays a group by pays_id);
-- nous pouvons aussi créer une vue, qui sera utilisée en place de la table bancale.
select * from personne left join pays_uv on pays_naiss = pays_id;
create table pays_umqt (pays_id, libelle) as
(select pays_id, (select libelle from pays b where a.pays_id = b.pays_id fetch first row only) from pays a group by pays_id)
data initially immediate
refresh deferred
maintained by user;
-- nous pouvons aussi créer une materialized query table.
select * from personne left join pays_umqt on pays_naiss = pays_id;
-- Autres solutions bienvenues !
/image%2F1025633%2F20151122%2Fob_b0e74c_pam007i.png)