PerlMSI
présentation

blog

archives

références

copyrights

télécharger

contact

Le PMSI avec PERL et Postgres SQL et R et ...
Quels croisements SQL peut on faire ?

J'ai trouvé lors de mes navigation un très bon exemple des différents types de join avec PostgreSQL. Prenons donc 2 tables:

  • t1
  •  num | name
    -----+------
       1 | a
       2 | b
       3 | c
    
  • t2
  •  num | value
    -----+-------
       1 | xxx
       3 | yyy
       5 | zzz
    
On va leur appliquer différents type de jointures : les résultats parlent d'eux même !
  • CROSS JOIN
  • => SELECT * FROM t1 CROSS JOIN t2;
     num | name | num | value
    -----+------+-----+-------
       1 | a    |   1 | xxx
       1 | a    |   3 | yyy
       1 | a    |   5 | zzz
       2 | b    |   1 | xxx
       2 | b    |   3 | yyy
       2 | b    |   5 | zzz
       3 | c    |   1 | xxx
       3 | c    |   3 | yyy
       3 | c    |   5 | zzz
    (9 rows)
    
  • INNER JOIN
  • => SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;
     num | name | num | value
    -----+------+-----+-------
       1 | a    |   1 | xxx
       3 | c    |   3 | yyy
    (2 rows)
    
    => SELECT * FROM t1 INNER JOIN t2 USING (num);
     num | name | value
    -----+------+-------
       1 | a    | xxx
       3 | c    | yyy
    (2 rows)
    
  • NATURAL INNER JOIN
  • => SELECT * FROM t1 NATURAL INNER JOIN t2;
     num | name | value
    -----+------+-------
       1 | a    | xxx
       3 | c    | yyy
    (2 rows)
    
  • LEFT JOIN
  • => SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;
     num | name | num | value
    -----+------+-----+-------
       1 | a    |   1 | xxx
       2 | b    |     |
       3 | c    |   3 | yyy
    (3 rows)
    
    => SELECT * FROM t1 LEFT JOIN t2 USING (num);
     num | name | value
    -----+------+-------
       1 | a    | xxx
       2 | b    |
       3 | c    | yyy
    (3 rows)
    
  • RIGHT JOIN
  • => SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;
     num | name | num | value
    -----+------+-----+-------
       1 | a    |   1 | xxx
       3 | c    |   3 | yyy
         |      |   5 | zzz
    (3 rows)
    
  • FULL JOIN
  • => SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;
     num | name | num | value
    -----+------+-----+-------
       1 | a    |   1 | xxx
       2 | b    |     |
       3 | c    |   3 | yyy
         |      |   5 | zzz
    (4 rows)
    
Vous voilà fin prêt pour utiliser les scripts PerlMSI créant des bases PostgreSQL !

 


 

Quelques trucs de formattage de fichiers texte

Les fichiers CSV sont pratiques, mais parfois il faut les retravailler... Ces quelques astuces devraient vous faire gagner du temps !

  • RegExp avec l'éditeur VI
  • Pour convertir le fichier csv en csv avec decimal-separator=.
    :%s/\("\d\+\),/\1./g
    
    S'il est sans guillemets:
    :%s/\(;\d\+\),/\1./g
    
    Pour supprimer les guillemets autour des nombres
    :%s/;"\(\d\+\)";/;\1;/g
    
    Pour supprimer les 0 après le point
    :%s/\(\d\+\).00/\1/g
    
    Pour recoder la date européenne (jour, mois, année) en date iso (année, mois, jour)
    :%s/\(\d\d\)\/\(\d\d\)\/\(\d\d\d\d\)/\3-\2-\1/g
    
  • Transcodage avec le programme iconv
    Format des accents : (possibilité de mettre US ASCII aussi)
    iconv -f CP1251 -t US -c  in > out
    
    Format des dates
    iconv -f CP1251 -t US -c  in > out
    
  • Import/Export dans PostGreSQL de fichiers CSV
  • Pour importer les csv dans une table
    copy table from '/tmp/fichier.csv' delimiters ',' CSV
    
    Pour exporter une table dans un CSV
    \copy table to '/tmp/fichier.csv' delimiters ';'
    
    Bien sur, on peut choisir son délimiteur - ici la virgule ou le point virgule.
    
    Il faut créer une table avant d'y importer un fichier.
    
    Pour cela, n ommer et typer les colonnes:
    create table cmd (cmd_code_pk smallint, cmd_lib char(255), cmd_ver char(5);
    create table diag (diag_code_pk char(10) PRIMARY KEY, diag_lib char(255), diag_ver);
    
  • Indexer une base
  • Pour accélérer les accès, indexer les colonnes de croisements:
    
    create index rss_2007_ghm_idx on rss_2007(ghm);
    
    Pour supprimer les index, on fait comme pour les séquences :
    
    delete index rss_2007_ghm_idx;
    
    Pour supprimer une table avec ses index et séquences:
    
    drop table rss_2007 cascade; 
    
  • Pour vérifier le bon chargement d'un RSS
  • Décompter par année le nombre d'IEP uniques, de RSS uniques, et de RUM:

    select annee, count(distinct iep) as iep, count(distinct rss) as rss, count(rss) as rum
    from (select iep, rss, uf, extract (year from date_debut_hospit) as annee from a_sejour)
    as subref group by annee;

À vous d'utiliser les scripts PerlMSI, par exemple RSS2SQL, pour vous entrainer maintenant!

 


 

Les variables en Perl
1. Les types

$scalar ="Hello World !\n";
@array = (1, 2, 3);
%hash   = ("laurel" => "hardy", "nick" =>  "nora", "nick" => "nolte");
# nick key is overwritten by nolte

1.1. Accéder aux différents types

print $scalar;
print "@array"; # 123
print %hash; # laurelhardynicknolte
print keys(%hash); # laurelnick
print values(%hash); # hardynolte

1.2. Les résultats dépendent du contexte d'accès

print $hash{nick}; # nolte : $ pour avoir la valeur, { pour dire la clef
print @array; # 3 because car il y a 3 éléments, et l'accès de print est scalar
my $size=scalar(@array); # ici on stocke 3
my @copy_array=@array; # ici on stocke (1, 2, 3)

$,=","; # Définition d'un séparateur pour faire joli
print %hash; # laurel,hardy,nick,nolte

1.2. Références symboliques:

$whattoprint = 'scalar';
print ${$whattoprint};
$name = "bam";
$$name = 1;                # Stocke 1 dans $bam
$name->[0] = 4;            # Stocle le premier élément de @bam
$name->{X} = "Y";          # Le X ième élément de %bam sera Y
@$name = ();               # Vide @bam
keys %$name;               # Donne les keys %bam
&$name;                    # Appele &bam

1.3. Références symboliques risquées

Utiliser plutôt « use strict 'refs'; »

${identifier};    # Comme $identifier, avec lexical scoping
${"identifier"};  # Comme $identifier, mais avec une référence symbolique

1.4. Lexical scoping

Il est possible de ne pas toucher aux variables globales si l'on a besoin
dans une fonction de variables locales ayant le même nom.

Mieux: on peut accéder quand même aux variables globales !

our $value  = "global";
{
    my $value = "private";
    print "Inside, mine is ${value}, ";
    print "but ours is ${'value'}.\n";
}
print "Outside, ${value} is again ${'value'}.\n";

2. Créer des références avec le backslash:

$scalarreference = \$scalar;
$arrayreference = \@array;
$hashreference = \%hash;
$codereference = \&subroutine;
$filereference = \*STDOUT;

2.1. Créer une référence à un scalar avec un backslash

$tenreference = \10;
$helloworldreference = \"hello world";

2.2. Créer une référence à un scalar situé dans un hash ou un array

$arrayfirstelementreference = \$array[1];
$hashlaurelkeyreference  = \$hash{"laurel"};
                                  
3. Déréférencer pour accéder au contenu

Tout celà sont des scalar :

$$scalarreference; # hello world
$$arrayreference; # (1, 2, 3)
$$hashreference;
$$codereference;
$$filereference;

3.1. Accéder aux référence de hash ou de arrays

On peut utiliser des scalar :

print $array[2]; # 3
print $$arrayreference[2]; # 3
print ${ $arrayreference}[2];
print $arrayreference->[2];

print $hash{"laurel"};
print $$hashreference{"laurel"};
print ${ $hashreference} {"laurel"};
print $hashreference->{"laurel"};

3.2. Modifier des références de hash ou de arrays

On ne peut pas utiliser des scalar, on doit retyper :

push (@$arrayreference, 4);  # Utilise indirectement la reférence à l'array

4. Créer des références à des types anonymes

D'abord, utiliser [{ au lieu de ( pour le contenu initial
Ensuite, le type sera un $ scalar car il s'agit d'une reference, non d'un % hash

@some_array = (1, 2, 3);
$reference_anonymous_array = [1, 2, 3];

%some_hash= ('alpha' => 1, 'beta' => 2, 'gamma' => 3);
$reference_anonymous_hash = {'alpha' => 1, 'beta' => 2, 'gamma' => 3};
	
my $sub_ref = sub { print "In a subroutine\n" };