Du mal pour une requète

Du mal pour une requète - SQL/NoSQL - Programmation

Marsh Posté le 09-03-2004 à 18:05:07    

Bon en fait il ne s'agit pas d'une reqête mais du vue, mais ca change pas mon probléme.
 
Je dois faire calculer le CA répartit par pays.
J'ai donc crées 2 vues qui ont la même structures et qui ressemble à ca :
 
vue1 : Pays | Total des factures
vue2 : Pays | Total des avoirs
 
Concrètement j'obtiens :
France     50000
Allemagne  35000
Belgique   23000
...
 
J'ai commencé ainsi car les avoirs et les ventes sont dans des tables distinctes.
Dans mon ultimes requète je souhaite faire la soustraction entre les factures et les avoirs.
Sauf que tout les pays faisant l'objet de facturation, ne font pas forcément l'objet d'avoir, et pour toute ces lignes, j'obtiens la valeur [NULL], la soustraction devenant impossible.
 
Des idées ? ma démarche n'est peut-être pas la bonne...
 
 
SELECT     dbo.[Statistique Série CA par Pays (factures)].Pays AS Pays,  
                      dbo.[Statistique Série CA par Pays (factures)].[Total des factures] - dbo.[Statistique Série CA par Pays (avoirs)].[Total des avoirs] AS CA
FROM         dbo.[Statistique Série CA par Pays (avoirs)] RIGHT OUTER JOIN
                      dbo.[Statistique Série CA par Pays (factures)] ON dbo.[Statistique Série CA par Pays (avoirs)].Pays = dbo.[Statistique Série CA par Pays (factures)].Pays

Reply

Marsh Posté le 09-03-2004 à 18:05:07   

Reply

Marsh Posté le 09-03-2004 à 19:11:59    

Utilise la fonction MVL et remplace null par 0

Reply

Marsh Posté le 10-03-2004 à 08:18:23    

Saurais-tu être plus précis sur la facon d'utiliser cette fonction, car je n'en ai jamais entendu parlé .
 
Merci

Reply

Marsh Posté le 10-03-2004 à 08:28:22    

C'est quoi comme base?

Reply

Marsh Posté le 10-03-2004 à 08:31:48    

sql serveur 2000

Reply

Marsh Posté le 10-03-2004 à 10:25:56    

J'ai pas très bien compris.
 
Tu veux faire quoi au juste ?
 
C'est quoi la structure de tes données ? Parceque faire une vue pointant sur d'autres vues, j'ai pas déjeuné, et la bile laisse un mauvais goût dans la bouche quand on vomit, alors évite.

Reply

Marsh Posté le 10-03-2004 à 10:31:01    

Ah, et un autre truc... C'est quoi ces noms batards ? Tu peux pas utiliser des VRAIS noms de table ?
 
V_TOTAT_FACTURES_PAYS pour la vue des factures par pays
V_TOTAL_AVOIRS_PAYS pour la vue des avoirs par pays
 
Parceque les noms à ralonge entre rochets et avec des parenthèses, utilise access si tu veux faire une base de porc, là t'es sur une base professionnelle, alors bosse comme un professionnel...


Message édité par MagicBuzz le 10-03-2004 à 10:31:43
Reply

Marsh Posté le 10-03-2004 à 10:40:59    

PS: sorti de ça, je vois pas ce qui cloche avec ta requête...
 
Mise à part que ton système est pourri si tu te base pas sur la table PAYS...
 
Les pays qui n'ont pas d'avoir ou pas de facture n'apparaîtront pas dans la vue, du coup elle sera inutilisable selon ce que tu veux en faire...

Reply

Marsh Posté le 10-03-2004 à 10:50:05    

La structure de mes tables (pour ce qui nous concerne) :
 
une table pays avec un codepays et une désignation  
une table entêtefacture avec un numéro de facture est un codepays du donneur d'ordre
une table lignefacture avec un numéro de facture est un montantligne
une table entêteavoir avec un numérod'avoir est un codepays donneur d'ordre
une table ligne avoir avec un numérod'avoir est un montantligne
 
Si j'ai éclaté mon truc en plusieurs vues (ou sous-requêtes), c'est avant tout pour essayer de simplifier les choses.
Tout faire en un seul coup, je ne suis pas contre, mais je ne parvient déjà pas à mes fins en séparant les problémes...
 
Pour ce qui est des noms, je suis d'accord avec toi sur le principe mais pour l'utilise lambda qui a besoin de se servir de cette vue(le nom de la vue apparait directement), et bien un nom long est bien plus parlant et agréable qu'un truc à la "DOS_LIKE". On est pas tous informaticiens !
 
En fait tout les pays qui sont présents dans ma requète caavoir, le sont forcément dans la table cafacture, mais l'inverse n'est pas vrai, j'ai beaucoup de pays facturés qui ne font pas l'objet d'avoirs. Et pour toutes ces lignes, la requète ne fonctionne pas puisqu'elle retire la valeur [nNULL] à CAfacture, et  
cafacture-[NULL] n'a pas pour résultat Cafacturé mais donne [NULL].
 
En fait il faudrait
SI caavoir vaut null, il prenne pour faire le calcul la valeur 0.
 
J'obtiens pour l'instant 2 tables de même structures qu'il me suffirait de mettre bout à bout et de faire la somme/par pays pour avoir exactement ce que je veux. mais je n'y arrive pas !!!


Message édité par capof le 10-03-2004 à 11:04:48
Reply

Marsh Posté le 10-03-2004 à 11:08:09    

OK.
 

select p.codpay, p.designation, sum(amounts) ca
from pays p, (
   select f.codpay, sum(fl.montantligne) amount
   from facture f, facute_ligne fl
   where fl.facture_num = f.num
   union all
   select a.codpay, sum(al.montantligne) * -1 amount
   from avoir a, avoir_ligne al
   where al.facture_num = a.num
) eve
where eve.codpay =* p.codpay
group by codpay


 
PS: Je te conseille de faire une vue "v_evenement", ça sert généralement pas mal...
 
 
select 'F' typeve, f.codpay, f.num, sum(fl.montantligne) amount
from facture f, facute_ligne fl
where fl.facture_num = f.num
union all
select 'A' typeve, a.codpay, a.num, sum(al.montantligne) amount
from avoir a, avoir_ligne al
where al.facture_num = a.num
 
Avec d'autres infos (client, produits, etc.)
 
PS: t'as le choix dans la requête entre un champ 'typeve' contenant 'F' ou 'A' selon facture ou avoir, ou alors, multiplier par -1 les montants d'avoir.
Je préfère la première solution, car tu n'est jamais à l'abris de données négatives dans les tables, et ça peut baiser les calcules entre la vue et des extracts bruts.
 
Dans l'absolu, cette vue "evenement" ne devrait pas être une vue, mais la table unique qui gère factures et avoirs.
 
Sur l'ERP sur lequel je travail, on a :
 
EVE : entêtes des factures, commandes, livraisons, etc.
EVL : lignes
EVP : "postes" (sous-lignes, par exemple, chaque envois d'une partie d'une ligne pour un typeve = 'LIV')
 
 
PS: pour le =* , je sais plus s'il est du bon côté. En tout cas, met-le : c'est pas parcequ'aujourd'hui tous les pays ont des lignes que ce sera toujours vrai.


Message édité par MagicBuzz le 10-03-2004 à 11:09:32
Reply

Marsh Posté le 10-03-2004 à 11:08:09   

Reply

Marsh Posté le 10-03-2004 à 11:10:36    

PS²: et te pose pas de question à propos de la lenteur éventuelle de la sous-requête, elle ne posera aucun problème. indexe bien la colonne "codpay" par contre.

Reply

Marsh Posté le 10-03-2004 à 13:16:43    

Il m'a fallu pas moins de 3 sous-requètes mais finalement j'arrive à ce que je voulais ! grâce à la fonction UNION ALL, que je ne connaissais pas !
 
Merci MagicBuzz ...
 
PS : je vais voir si y'a pas moyen de faire tout ca en une fois maintenant !


Message édité par capof le 10-03-2004 à 13:17:23
Reply

Marsh Posté le 10-03-2004 à 16:29:01    

pkoi t'as pas repris la structure de ma requête ? je l'ai pas testée, mais à priori elle est bonne. je fais des requêtes comme ça tous les jours (sous oracle par contre, mais la syntaxe change pas pour ce type de requêtes)

Reply

Marsh Posté le 10-03-2004 à 16:32:33    

En fait j'ai pas repris exactement la tienne car ma requète initiale est plus compliqué que ce que j'ai expliqué... J'ai focalisé ce topic sur mon probléme. En tout cas je te remercie.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed