Bonsoir Samaelarcangelo,

Envoyé par
Samaelarcangelo
En gros ma table ressemble à cela
Cette structure a tout l’air d’être correcte.
Toutefois, vous dites qu’un dossier engendre une seule vente : si tel est le cas il faudrait mettre en œuvre deux tables, une pour la partie ventes, une pour la parie achats, sachant que par jointure de ces deux tables on retrouve EPV, qui dégénérerait alors en vue de jointure.
En poussant, au vu de votre exemple, EPV pourrait être une vue de jointure de trois tables : VENTE, ACHAT, FRET, à moins qu’une règle de gestion précise qu’à un dossier correspondent plusieurs frets. Quelles sont les règles exactes ?
Si la décomposition est possible, alors on aurait la structure suivante :
Table VENTE :
1 2 3 4
| COD_ANA TYP_PIE COD_PRT MNT_NAP
------- ------- ------- -------
P14.001 prof1 client 35000.00
P14.002 prof1 client 8000.00 |
Table ACHAT :
1 2 3 4 5 6
| COD_ANA TYP_PIE COD_PRT MNT_NAP
------- ------- ------- -------
P14.001 comm1 fournisseur1 12000.00
P14.001 comm2 fournisseur1 10000.00
P14.001 comm1 fournisseur2 5000.00
P14.002 comm1 fournisseur1 4000.00 |
Table FRET :
1 2 3 4
| COD_ANA TYP_PIE COD_PRT MNT_NAP
------- -------- ------- -------
P14.001 comm1 affreteur1 2000.00
P14.002 comm1 affreteur 1000.00 |
Plus précisément, et en en faisant des hypothèses quant aux clés primaires (sans les clés, on ne peut pas modéliser) :
VENTE {COD_ANA, TYP_PIE, COD_PRT, MNT_NAP} PRIMARY KEY {COD_ANA}
ACHAT { COD_ANA, TYP_PIE, COD_PRT, MNT_NAP} PRIMARY KEY {COD_ANA, COD_PRT, TYP_PIE}
FRET { COD_ANA, TYP_PIE, COD_PRT, MNT_NAP} PRIMARY KEY {COD_ANA}
A vous de dire si ces structures (et les clés primaires) correspondent à la réalité.
Quant à la vue (informellement) :
EPV = JOIN VENTE, ACHAT, FRET USING (COD_ANA)
Quoi qu’il en soit, voici comment produire le résultat attendu, en utilisant PostgreSQL. Je détaille :
1re brique : comme vous l’avez fait, on filtre sur 'P14%' :
1 2 3 4
| SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP,
ROW_NUMBER() OVER (PARTITION BY COD_ANA) AS rowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%' |
=>
1 2 3 4 5 6 7 8 9 10
| COD_ANA COD_JRN TYP_PIE COD_PRT MNT_NAP RowNum
------- ------- ------- ------- ------- ------
P14.001 achat comm1 fournisseur1 12000.00 1
P14.001 achat comm2 fournisseur1 10000.00 2
P14.001 vente prof1 client 35000.00 3
P14.001 achat comm1 fournisseur2 5000.00 4
P14.001 fret comm1 affreteur1 2000.00 5
P14.002 fret comm1 affreteur 1000.00 1
P14.002 achat comm1 fournisseur1 4000.00 2
P14.002 vente prof1 client 8000.00 3 |
Vous observerez que la fonction ROW_NUMBER() a permis de partitionner COD_ANA en P14.001 et P14.002, tout en numérotant les lignes à partir de 1, pour chaque COD_ANA.
2e brique :
On ajoute les lignes « en-tête » P14.001 et P14.002, en leur affectant 0 comme numéro de ligne (colonne RowNum) :
1 2 3
| SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS MNT_NAP
FROM EPV
WHERE COD_ANA LIKE 'P14%' |
=>
1 2 3 4
| COD_ANA MNT_NAP RowNum
------- ------- ------- ------- ------- ------
P14.001 0.00 0
P14.002 0.00 0 |
On procède maintenant à l’union des deux requêtes qui précèdent, en triant le résultat sur (COD_ANA, RowNum) :
1 2 3 4 5 6 7 8 9
| SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP,
ROW_NUMBER() OVER (PARTITION BY COD_ANA) AS rowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%'
UNION
SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS RowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%'
ORDER BY COD_ANA, RowNum |
=>
1 2 3 4 5 6 7 8 9 10 11 12
| COD_ANA COD_JRN TYP_PIE COD_PRT MNT_NAP RowNum
------- ------- ------- ------- ------- ------
P14.001 0.00 0
P14.001 achat comm1 fournisseur1 12000.00 1
P14.001 achat comm2 fournisseur1 10000.00 2
P14.001 vente prof1 client 35000.00 3
P14.001 achat comm1 fournisseur2 5000.00 4
P14.001 fret comm1 affreteur1 2000.00 5
P14.002 0.00 0
P14.002 fret comm1 affreteur 1000.00 1
P14.002 achat comm1 fournisseur1 4000.00 2
P14.002 vente prof1 client 8000.00 3 |
Mise en forme finale (qu’EPV soit une table ou une vue) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| SELECT CASE WHEN rowNum > 0 THEN COD_JRN ELSE COD_ANA END AS COD_ANA
, CASE WHEN rowNum > 0 THEN TYP_PIE ELSE '' END AS TYP_PIE
, CASE WHEN rowNum > 0 THEN COD_PRT ELSE '' END AS COD_PRT
, CASE WHEN rowNum > 0 THEN MNT_NAP END AS MNT_NAP
FROM
(
SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP,
ROW_NUMBER() OVER (PARTITION BY COD_ANA) AS rowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%'
UNION
SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS RowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%'
ORDER BY COD_ANA, COD_JRN, TYP_PIE, COD_PRT
) AS truc ; |
=>
1 2 3 4 5 6 7 8 9 10 11 12
| COD_ANA TYP_PIE COD_PRT MNT_NAP
------- ------- ------- -------
P14.001
achat comm1 fournisseur1 12000.00
achat comm2 fournisseur1 10000.00
vente prof1 client 35000.00
achat comm1 fournisseur2 5000.00
fret comm1 affreteur1 2000.00
P14.002
fret comm1 affreteur 1000.00
achat comm1 fournisseur1 4000.00
vente prof1 client 8000.00 |
Version SQL Server (qui veut que la clause ORDER BY soit rapatriée dans OVER) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| SELECT CASE WHEN rowNum > 0 THEN COD_JRN ELSE COD_ANA END AS COD_ANA
, CASE WHEN rowNum > 0 THEN TYP_PIE ELSE '' END AS TYP_PIE
, CASE WHEN rowNum > 0 THEN COD_PRT ELSE '' END AS COD_PRT
, CASE WHEN rowNum > 0 THEN MNT_NAP END AS MNT_NAP
FROM
(
SELECT COD_ANA, COD_JRN, TYP_PIE, COD_PRT, MNT_NAP,
ROW_NUMBER() OVER (PARTITION BY COD_ANA ORDER BY COD_ANA) AS rowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%'
UNION
SELECT DISTINCT COD_ANA, '', '', '', 0.00, 0 AS RowNum
FROM EPV
WHERE COD_ANA LIKE 'P14%'
) AS truc ; |
Si vous utilisez un SGBD ne proposant pas la fonction ROW_NUMBER(), ou l'équivalent, ça risque d’être beaucoup plus compliqué...
Partager