bessere lösung als x-mal left join?
am 20.01.2007 14:40:31 von office
hallo
Ich zermarter mir den Kopf über eine eigentlich einfache aber nicht in
SQL umsetzbare lösung - oder doch?
gegeben 2 tabellen
(einfache darstellung, da original sehr komplex)
Tab 1: id, wert1, wert2, wert3 (werte sind nummerisch von 0 beginnend
=3D kein eintrag)
Tab 2: id, inhalt
Die Wichtigkeit der Werte aus Tab1 steigt mit der Zahl dahinter (=3D
multiplikator)
Die id aus Tab2 ist mit einem oder mehrer werte in Tab1 verknüft
Gesucht wird nur in Tab2 nach einer sehr komplexen abfrage.
Ergebnis, eine "Liste" mit werten, anhand derer nun die besten
übereinstimmunen
in Tab1 gefunden werden sollen.
Als Endergebnis wird eine Liste der id's aus der Tab1 nach relevanz
benötigt.
Beispiel für Tab1:
1 , 1 , 2 , 0
2 , 0 , 1 , 1
3 , 2 , 3 , 1
Beispiel für Tab2:
1, 'a'
2, 'b'
3, 'c'
gesucht wird nun nach 'b,c' (reihenfolge ist beliebig)
Ergebnis aus Tab1
3 (1*1, 2*1(c),1*0(0) =3D 3)
1 (1*0(a) , 2*1(b) , 0 =3D 2)
2 (0 , 2*0(a) , 3*0(a) =3D 0)
Die Lösung wird zur Zeit mit left join ermittelt:
select tab1.id, j1.filter *1 + j2.filter *2 + j3.filter *3 as xorder
from tab1
left join tab2 as j1
on j1.id =3D wert1 and ( inhalt =3D filter )
left join tab2 as j2
on j2.id =3D wert2 and ( inhalt =3D filter )
left join tab2 as j3
on j3.id =3D wert3 and ( inhalt =3D filter )
order by xorder
nun ist die "filter"-Abfrage sehr komplex muß aber bei dieser Lösung
3x ausgeführt werden, was nicht
sehr perfomant ist
Gibt es eine Lösung, wo die "filter"-Abfrage nur einmal ausgeführt
werden muß?
So nach dem Motto:
select tab1.id, wert1*1 wenn enthalten in filter
+ wert2*2 wenn enthalten in filter
+ wert3*3 wenn enthalten in filter as xorder
from tab1 left join (filter) order by xorder
Ach ja, 2 SQL-Statements sind nicht das gelbe vom Ei, da diese
Konstrukt wiederum als Join
für eine weitere Abfrage dient.
Danke für Anregungen=20
nOlivier
Re: bessere lösung als x-mal left join?
am 20.01.2007 21:09:44 von Heiko Richler
n.Olivier wrote:
> (einfache darstellung, da original sehr komplex)
>
> Tab 1: id, wert1, wert2, wert3 (werte sind nummerisch von 0 beginnend
> = kein eintrag)
> Tab 2: id, inhalt
Das ist doch n:m, oder? Ein Datensatz aus Tab1 steht zu m Datensätzen
aus Tab2 in Beziehung und einer aus Tab2 kann bei n Datensätzen aus Tab1
vorkommen, richtig?
Dann solltest Du versuchen diese Beziehung über eine verknüpfende
Tabelle darzustellen.
Tab1: id, ...
Tab2: id, inhalt
Tab12: Tab2_id, Tab1_id, Wichtigkeit
> (werte sind nummerisch von 0 beginnend = kein eintrag)
Finde ich nicht schön. Etwas besser wäre null = kein Eintrag
> Die Lösung wird zur Zeit mit left join ermittelt:
> select tab1.id, j1.filter *1 + j2.filter *2 + j3.filter *3 as xorder
> from tab1
> left join tab2 as j1
> on j1.id = wert1 and ( inhalt = filter )
> left join tab2 as j2
> on j2.id = wert2 and ( inhalt = filter )
> left join tab2 as j3
> on j3.id = wert3 and ( inhalt = filter )
> order by xorder
>
> nun ist die "filter"-Abfrage sehr komplex muß aber bei dieser Lösung
> 3x ausgeführt werden, was nicht
> sehr perfomant ist
select tab1.id,
(select sum(Tab12.Wichtigkeit * Tab2.filter)
from Tab12 inner join tab2 on tab2.id=Tab12.Tab2_id
where tab1.id=Tab12.Tab1_id and ( inhalt = filter ) as xorder
> select tab1.id, wert1*1 wenn enthalten in filter
> + wert2*2 wenn enthalten in filter
> + wert3*3 wenn enthalten in filter as xorder
> from tab1 left join (filter) order by xorder
Alternativ erzeugt Du dir für den Teil rechts von join eine View oder
eine temporäre Tabelle. Das könntest Du natürlich auf für das innere
Select meiner Idee machen.
Heiko
--
http://portal.richler.de/ Namensportal zu Richler
http://www.richler.de/ Heiko Richler: Computer - Know How!
http://www.richler.info/ private Homepage
Re: bessere lösung als x-mal left join?
am 23.01.2007 11:14:49 von office
Heiko Richler schrieb:
> n.Olivier wrote:
> > (einfache darstellung, da original sehr komplex)
> >
> aus Tab2 in Beziehung und einer aus Tab2 kann bei n Datensätzen aus Tab1
> vorkommen, richtig?
>
> Dann solltest Du versuchen diese Beziehung über eine verknüpfende
> Tabelle darzustellen.
>
> Tab1: id, ...
> Tab2: id, inhalt
> Tab12: Tab2_id, Tab1_id, Wichtigkeit
mh, an dies habe ich noch nicht gedacht,
allerdings könnte dies sehr aufwändig werden
210000 * 50000 DS zur Zeit und noch nicht einmal
5% der maximalen Eitnräge in beiden Tabellen
andererseits könnte dies Lösung die Abfrage enorm
beschleunigen ... werde also mal antesten ob es möglich ist
> > (werte sind nummerisch von 0 beginnend =3D kein eintrag)
>
> Finde ich nicht schön. Etwas besser wäre null =3D kein Eintrag
mit .null. lässt sich schlecht rechnen, daher 0
> > Die Lösung wird zur Zeit mit left join ermittelt:
> > select tab1.id, j1.filter *1 + j2.filter *2 + j3.filter *3 as xorder
[..]
> > + wert3*3 wenn enthalten in filter as xorder
> > from tab1 left join (filter) order by xorder
>
> Alternativ erzeugt Du dir für den Teil rechts von join eine View oder
> eine temporäre Tabelle. Das könntest Du natürlich auf für das inn=
ere
> Select meiner Idee machen.
Bei Temp bin ich mittlerweile auch gelandet, da dies die noch
schnellste Lösung (zur Zeit) ist.
Danke und Gruß
nOlivier