Join auf Staffelwerte

Snoopy1959

Benutzer
Beiträge
10
Join auf Staffelwerte
Hallo Zusammen
ich habe in einer Tabelle Transkosten einen Staffelwert.
In der Tabelle Distanzen habe ich die echten Distanzen vom Lagerort zum Lieferort

Wie hänge ich nun die beiden Tabelle zusammen?
Select Distanz , trspkosten
from tblDistanz d
Left Join Transkosten tk
on
d.Distanz >= tk.Staffelwert
and
d.Distanz <= tk.Staffelwert
;
Dieser Ansatz hat nur bei den Distanzen funktioniert, bei denen die Distanz genau einem Staffelwert entsprach.

Wie macht man das richtig?

Danke für jede Hilfe
Snoopy
 
Werbung:
sehe auf den ersten Blick keinen Fehler. Passen die Datentypen?

Ich würde es in PostgreSQL so lösen:

Code:
test=*# select * from staffeln ;
 von_bis | wert
---------+------
 [0,10)  |   10
 [10,20) |   20
 [20,30) |   30
(3 rows)

test=*# select * from transport ;
 id | distanz
----+---------
  1 |       5
  2 |      15
  3 |      20
(3 rows)

test=*# select * from transport t left join staffeln s on t.distanz <@ s.von_bis;
 id | distanz | von_bis | wert
----+---------+---------+------
  1 |       5 | [0,10)  |   10
  2 |      15 | [10,20) |   20
  3 |      20 | [20,30) |   30
(3 rows)

test=*#

aber so gut sind natürlich kommerzielle Datenbanken nicht ...
 
Der Fehler ist natürlich das Gleichheitszeichen, deine Bedingungen lassen sich auch mit
Code:
d.Distanz = tk.Staffelwert
ausdrücken. Dein Staffelwert hat vermutlich einen Wert von/bis der abgedeckt werden soll, da muss sich also ein 2ter Wert ergeben. Beispiel:
Code:
d.Distanz BETWEEN tk.Staffelwert AND tk.Staffelwert + 1
 
Der Fehler ist natürlich das Gleichheitszeichen, deine Bedingungen lassen sich auch mi

Welches Gleichheitszeichen beim Fragesteller?

Ich stelle meine Tabelle mal um und verwende seine Abfrage:

Code:
test=*# create table staffeln_new as select lower(von_bis) as von, upper(von_bis) as bis, wert from staffeln;
SELECT 3
test=*# select * from transport t left join staffeln_new s on t.distanz >= s.von and t.distanz < s.bis;
 id | distanz | von | bis | wert
----+---------+-----+-----+------
  1 |       5 |   0 |  10 |   10
  2 |      15 |  10 |  20 |   20
  3 |      20 |  20 |  30 |   30
(3 rows)

test=*#

einziger Unterschied: der obere Grenzwert. Bei RANGE-Typen ist der impliziet exclusive, daher muß hier auch dann < verwendet werden, nicht <=. Meinst Du das?

Oder hab ich den Fragesteller völlig falsch interpretiert? Ich hatte eigentlich es so verstanden, daß es darum geht, Transportkosten für verschiedene Entfernungsbereiche zu definieren.
Jetzt fällt mir grad auf:

Code:
d.Distanz >= tk.Staffelwert
and
d.Distanz <= tk.Staffelwert

Dann macht natürlich auch Sinn, wenn er schreibt:

Dieser Ansatz hat nur bei den Distanzen funktioniert, bei denen die Distanz genau einem Staffelwert entsprach.

An den Fragesteller: es wäre absolut sinnvoll, nachvollziehbare Beispiele als nur, sorry, Geschwurbel zu zeigen ...

  • Tabellendefinitionen
  • Beispieldaten
  • gewünschtes Ergebniss
  • versuchte Abfrage
  • erhaltenes Ergebniss

Das wäre zielführend.
 
Code:
d.Distanz >= tk.Staffelwert
and
d.Distanz <= tk.Staffelwert
Ist gleichbedeutend mit
Code:
d.Distanz = tk.Staffelwert
Stimmt schon es sind nicht die Gleichheitszeichen sondern die Größer-/Kleinerzeichen so gesehen. Was er aber mit Sicherheit sucht ist eine Join-Condition die prüft ob d.Distanz innerhalb einer Range ist. tk.Staffelwert ist aber vermutlich kein Rangetyp, wäre mir neu in MSSQL :)
 
Danke für das Mitdenken,
der Ansatz mit
d.Distanz BETWEEN tk.Staffelwert AND tk.Staffelwert + 5
passt auf eine Staffelung mit dem Raster 5 zwischen den Werten.
Das ist eine brauchbare Lösung.
Was aber wenn die Staffelung unterschiedliche Abstände zwischen den Werten hat?

Distanzen
TL_PLZ1 Lief_PLZ1 Distanz
1214 1165 42.000000
1214 1166 39.000000
1214 1170 43.000000
1214 1172 38.000000
1214 1173 40.000000
1214 1174 42.000000
1214 1174 45.000000
1214 1180 36.000000
1214 1180 38.000000
1214 1182 33.000000

TrspTarif
Staffelwert Zu-/Abschlag
0 1.45
1 1.45
6 1.55
11 1.65
16 1.85
21 2.00
26 2.15
31 2.25
36 2.35
41 2.45

beispiel mit Between
SELECT d.[TL_PLZ1]
,d.[Lief_PLZ1]
,d.[Distanz]
,tk.[Zu-/Abschlag]
FROM [T_SRO].[dbo].[tbl_DSA_Distanz] d

Left Join [T_SRO].[dbo].[tbl_DSA_TrspTarif] tk
on
d.Distanz BETWEEN tk.Staffelwert AND tk.Staffelwert + 4

Danke Snoopy
 
Die Zeiträume die die Staffel abdeckt müssen sich irgendwie erschließen. Da gibt es dann verschiedene Ansätze, z.B. Wert bis Wert + X, Wert bis Wert * Faktor oder Wert bis nächster Wert. Es können der Start und der End-Wert der Staffel in der Tabelle eingetragen werden oder du joinst die Staffeltabelle mit sich selbst so das du jeweils den Folge-Startwert als Endwert nimmst.

Theoretisch kann der bei der Staffel eingetragene Wert ja auch der Mittelwert sein und du musst sowohl Start- als auch Endwert berechnen.
 
SELECT Distinct
d.[TL_PLZ1]
,d.[Lief_PLZ1]
,d.[Distanz]
,tk.Staffelwert
,tk.[Zu-/Abschlag]
FROM [T_SRO].[dbo].[tbl_DSA_Distanz] d

Left Join [T_SRO].[dbo].[tbl_DSA_TrspTarif] tk
on
d.Distanz > tk.Staffelwert
and
d.Distanz < tk.Staffelwert


order by d.distanz
 
Hallo Zusammen,
ich habe das Gefühl ich habe eine Lösung

With tmp
as
(
SELECT [TL_PLZ1]
,[Lief_PLZ1]
,[Distanz]
,t.staffelwert
,t.[Zu-/Abschlag]
,ROW_Number() over(Partition by TL_PLZ1, Lief_PLZ1 order by t.Staffelwert asc) as RowNr
FROM [T_SRO].[dbo].[tbl_DSA_Distanz] d

Left Join [dbo].[tbl_DSA_TrspTarif] t
on
d.Distanz < t.Staffelwert -1
or
d.Distanz = t.Staffelwert
)
Select TL_PLZ1
,Lief_PLZ1
,Distanz
,Staffelwert
,RowNr
,[Zu-/Abschlag]
From tmp
where RowNr = 1
go
;

Resultat
TL_PLZ1 Lief_PLZ1 Distanz Staffelwert RowNr Zu-/Abschlag
7302 7517 97.000000 101 1 3.80
7302 7522 249.000000 251 1 7.20
7302 7523 254.000000 256 1 7.30
7302 7524 259.000000 261 1 7.45
7302 7525 269.000000 271 1 7.65
7302 7526 119.000000 121 1 4.20
7302 7527 279.000000 281 1 7.85


Was denkt ihr?

Gruss

Snoopy
 
Werbung:
Ich glaube du suchst
Code:
Left Join [dbo].[tbl_DSA_TrspTarif] t
on
d.Distanz BETWEEN t.Staffelwert AND t.Staffelwert -1
Dein Code hat eine Schwäche, der Funktioniert warscheinlich nur bei der ersten Staffel. Wenn dein Staffelwert 2 ist (also der Werteberreich 2-3) dann würde 1 auch zugeorndet weil ist ja < 2+1.
 
Zurück
Oben