PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

type de jointure

Technique - général | type de jointure

Par jduv le 15/09/2006 - 14:44

Bonjour Ă  tous,

Je cherche Ă  trouver une jointure qui me permettrait de multiplier deux champs venant de deux tables distinctes (en fait 1 vue et une table).
Mon probléme est que s'il extiste bien un champ commun aux deux ensembles, les valeurs de celui ci dans ma table T1 n'existent pas forcément toutes dans ma table T2 et je voudrai utiliser le champ de T2 tant que le champ correspondant n'est pas atteint.

Je ne sais pas si je suis trés clair alors voici ce que j'ai.

Table1 (vue)
2 champs 1 date et un real

Table2
2 champs 1 date et un real

note : je n'ai pas réellement de champ date mais des id_date qui font références à une table qui contient toute les dates.

Table1
2000/01/01->10
2000/01/02->11
2000/01/03->12
2000/01/04->13
2000/01/05->14
2000/01/06->15
2000/01/07->16

Table2
2000/01/02->100
2000/01/04->1000
2000/01/07->10000

et voudrai faire une requete qui me fasse :

2000/01/01->(10*100) = 1000
2000/01/02->(11*100) = 1100
2000/01/03->(12*100) = 1200
2000/01/04->(13*1000) = 13000
2000/01/05->(14*1000) = 14000
2000/01/06->(15*1000) = 15000
2000/01/07->(16*10000) = 160000

En fait je garde le min des champs dates de la Table2 tant que le champ date de la Table1 n'a pas atteint une nouvelle valeur dans la table2
Je me doute que je doit aussi pouvoir le faire en utilisant un script php mais j'aimerai aussi le faire avec une requete SQL ??

J'espére être assez clair
Merci d'avance ?

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

Sympathique :-)

Jean-Paul Argudo/ = 16 Septembre, 2006 - 12:19

Voici une solution à ce sympathique problème que j'ai trouvée. Tout réside sur un coalesce(): cette fonction prends le 1er élément non nul.

J'utilise ainsi une jointure externe entre les deux table pour trouver les nuls (éléments de T2 n'existant pas dans T1), et les traiter.

select t1.a, (t1.b *
coalesce(
-- B existe dans la table T2
t2.b,

-- B n'existe pas dans la table T2
-- on prends l'élément le plus petit de T2
-- correspondant

(select tt2.b
from table2 tt2
where tt2.a < t1.a
order by tt2.a desc
limit 1),

-- B de T2 n'existe pas et de plus, la date est
-- la plus petite de T2

(select ttt2.b
from table2 ttt2
order by ttt2.a
limit 1)
)
) as resultat
from table1 t1
left join table2 t2 using (a);

a | resultat
------------+----------
2000-01-01 | 1000
2000-01-02 | 1100
2000-01-03 | 1200
2000-01-04 | 13000
2000-01-05 | 14000
2000-01-06 | 15000
2000-01-07 | 160000
(7 lignes)

QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
Merge Left Join (cost=406.03..1213747.81 rows=18818 width=12) (actual time=0.279..0.587 rows=7 loops=1)
Merge Cond: ("outer".a = "inner".a)
InitPlan
-> Limit (cost=135.34..135.34 rows=1 width=8) (actual time=0.056..0.060 rows=1 loops=1)
-> Sort (cost=135.34..140.19 rows=1940 width=8) (actual time=0.047..0.047 rows=1 loops=1)
Sort Key: a
-> Seq Scan on table2 ttt2 (cost=0.00..29.40 rows=1940 width=8) (actual time=0.006..0.021 rows=3 loops=1)
-> Sort (cost=135.34..140.19 rows=1940 width=8) (actual time=0.097..0.131 rows=7 loops=1)
Sort Key: t1.a
-> Seq Scan on table1 t1 (cost=0.00..29.40 rows=1940 width=8) (actual time=0.011..0.046 rows=7 loops=1)
-> Sort (cost=135.34..140.19 rows=1940 width=8) (actual time=0.051..0.066 rows=3 loops=1)
Sort Key: t2.a
-> Seq Scan on table2 t2 (cost=0.00..29.40 rows=1940 width=8) (actual time=0.007..0.023 rows=3 loops=1)
SubPlan
-> Limit (cost=64.46..64.46 rows=1 width=8) (actual time=0.042..0.045 rows=1 loops=4)
-> Sort (cost=64.46..66.07 rows=647 width=8) (actual time=0.032..0.032 rows=1 loops=4)
Sort Key: a
-> Seq Scan on table2 tt2 (cost=0.00..34.25 rows=647 width=8) (actual time=0.007..0.013 rows=1 loops=4)
Filter: (a < $0)
Total runtime: 0.714 ms
(20 lignes)

erkkk

En espérant que cela vous sera utile :-)

Cordialement,

--
Jean-Paul ARGUDO
www.dalibo.com


Effectivement cela m'est tré

jduv/ = 18 Septembre, 2006 - 11:17

Effectivement cela m'est trés utile.
J'Ă©tais sur une autre piste mais finalement moins directe que celle ci

Merci beaucoup pour la réponse si détaillée

JĂ©rĂ´me


© PostgreSQLFr, tous droits rĂ©servĂ©s.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.