(jour CHAR(8),
seq SMALLINT,
montant NUMERIC(13,2),
contrepartie CHAR(5),
PRIMARY KEY (jour, seq))
;
CREATE TABLE contrepartie
(contrepartie CHAR(5) PRIMARY KEY,
libellé VARCHAR(50))
;
Nous aimerions maintenant faire apparaître à la suite de chaque opération le libellé de la contrepartie. Pour ce faire nous devons réaliser une jointure entre les deux tables. Diverses possibilités s'offrent à nous.
Jointure intérieure (INNER JOIN):
bdtest-> FROM opération a INNER JOIN contrepartie b
bdtest-> ON a.contrepartie = b.contrepartie
bdtest-> ORDER BY a.jour, a.seq
bdtest-> ;
jour | seq | montant | libellé
----------+-----+---------+----------------
2011-255 | 2 | -400.00 | Epargne #1
2011-255 | 3 | -123.29 | Grande Surface
2011-255 | 4 | -150.00 | Alphonse
2011-256 | 2 | 57.49 | Epargne #2
(4 lignes)
Les deux colonnes qui sont jointes portent le même nom. Dans ce cas, nous aurions pu arriver au même résultat avec le query suivant:
FROM opération a NATURAL JOIN contrepartie b
ORDER BY a.jour
;
Nous devons donc utiliser un autre type de jointure:
Jointure extérieure gauche (LEFT OUTER JOIN):
bdtest-> FROM opération a NATURAL LEFT OUTER JOIN contrepartie b
bdtest-> ORDER BY a.jour, a.seq
bdtest-> ;
jour | seq | montant | libellé
----------+-----+---------+----------------
2011-255 | 1 | 1460.45 |
2011-255 | 2 | -400.00 | Epargne #1
2011-255 | 3 | -123.29 | Grande Surface
2011-255 | 4 | -150.00 | Alphonse
2011-256 | 1 | -48.00 |
2011-256 | 2 | 57.49 | Epargne #2
2011-257 | 1 | -28.27 |
(7 lignes)
bdtest-> FROM opération a NATURAL LEFT OUTER JOIN contrepartie b
bdtest-> WHERE b.contrepartie IS NULL
bdtest-> order by a.contrepartie
bdtest-> ;
contrepartie
--------------
autre
EL
RN
(3 lignes)
FROM opération a
WHERE NOT EXISTS
(SELECT *
FROM contrepartie b
WHERE b.contrepartie = a.contrepartie)
ORDER by a.contrepartie
;
FROM opération
WHERE contrepartie NOT IN
(SELECT contrepartie
FROM contrepartie )
ORDER by contrepartie
;
Jointure externe droite (RIGHT OUTER JOIN)
bdtest-> FROM opération a NATURAL RIGHT OUTER JOIN contrepartie b
bdtest-> ORDER BY a.jour
bdtest-> ;
jour | seq | montant | libellé
----------+-----+---------+----------------
2011-255 | 2 | -400.00 | Epargne #1
2011-255 | 3 | -123.29 | Grande Surface
2011-255 | 4 | -150.00 | Alphonse
2011-256 | 2 | 57.49 | Epargne #2
| | | Magasin
(5 lignes)
Et enfin...
Jointure complète (FULL JOIN)
bdtest-> FROM opération a NATURAL FULL JOIN contrepartie b
bdtest-> ORDER BY a.jour
bdtest-> ;
jour | seq | montant | libellé
----------+-----+---------+----------------
2011-255 | 1 | 1460.45 |
2011-255 | 2 | -400.00 | Epargne #1
2011-255 | 3 | -123.29 | Grande Surface
2011-255 | 4 | -150.00 | Alphonse
2011-256 | 1 | -48.00 |
2011-256 | 2 | 57.49 | Epargne #2
2011-257 | 1 | -28.27 |
| | | Magasin
(8 lignes)
Dans la table opération tous les montants sont dans une seule colonne. Il est possible de les afficher sur deux colonnes, une réservée aux crédits et une autre pour les débits:
bdtest-> CASE
bdtest-> WHEN montant > 0 THEN
bdtest-> montant
bdtest-> ELSE 0
bdtest-> END AS credit,
bdtest-> CASE
bdtest-> WHEN montant < 0 THEN
bdtest-> -montant
bdtest-> ELSE 0
bdtest-> END AS debit
bdtest-> FROM opération NATURAL LEFT OUTER JOIN contrepartie
bdtest-> ORDER BY jour;
jour | seq | libellé | credit | debit
----------+-----+----------------+---------+--------
2011-255 | 1 | | 1460.45 | 0
2011-255 | 2 | Epargne #1 | 0 | 400.00
2011-255 | 3 | Grande Surface | 0 | 123.29
2011-255 | 4 | Alphonse | 0 | 150.00
2011-256 | 1 | | 0 | 48.00
2011-256 | 2 | Epargne #2 | 57.49 | 0
2011-257 | 1 | | 0 | 28.27
(7 lignes)
Exportation vers un tableur
L'output de la requête ci-dessus peut-être redirigé vers un fichier et formaté de manière telle que les données puissent être facilement exportées vers un tableur. Pour ce faire, il suffit d'utiliser dans notre terminal psql les meta commandes suivantes:
\pset numericlocale (pour avoir par exemple 1.460,45 au lieu de 1460.45)
\a pour passer au mode de sortie non aligné
\t pour afficher uniquement les rangées (sans les en-têtes)
\f ';' pour initialiser le séparateur de champ à ';'
\o [FICHIER] pour envoyer le résultat de la requête vers le fichier FICHIER
\i [FICHIER] pour exécuter les commande du fichier FICHIER (ce n'est évidemment pas le même)
Affichage de la sortie numérique adaptée à la locale.
bdtest=> \t
Affichage des tuples seuls.
bdtest=> \f ';'
Le séparateur de champs est « ; ».
bdtest=> \o bilan.csv
bdtest=> \i opération.sql
bdtest=>
Rapidement nous arrivons à ceci:
CASE
WHEN montant > 0 THEN
montant
ELSE 0
END AS credit,
CASE
WHEN montant < 0 THEN
-montant
ELSE 0
END AS debit,
montant AS solde
FROM opération NATURAL LEFT OUTER JOIN contrepartie
UNION
SELECT 'Total' AS jour, 0 AS seq, '' AS libellé,
sum(credit) AS credit,
sum(debit) AS debit,
sum(solde) AS solde
FROM (SELECT
CASE
WHEN montant > 0 THEN
montant
ELSE 0
END AS credit,
CASE
WHEN montant < 0 THEN
-montant
ELSE 0
END AS debit,
montant AS solde
FROM opération NATURAL LEFT OUTER JOIN contrepartie
) a
ORDER BY jour, seq
;
Ce query:
jour,
sum(credit) AS credit,
sum(debit) AS debit,
sum(solde) as solde
FROM (SELECT jour,
CASE
WHEN montant > 0 THEN
montant
END AS credit,
CASE
WHEN montant < 0 THEN
-montant
END AS debit,
montant AS solde
FROM opération) a
GROUP BY jour
UNION
SELECT
'Total' AS jour,
sum(credit) AS credit,
sum(debit) AS debit,
sum(solde) AS solde
FROM (SELECT
CASE
WHEN montant > 0 THEN
montant
END AS credit,
CASE
WHEN montant < 0 THEN
-montant
END AS debit,
montant AS solde
FROM opération) a
ORDER BY jour
;
Post a Comment
Click to see the code!
To insert emoticon you must added at least one space before the code.