PDA

View Full Version : SQL - Datensätze untereinander darstellen . (xmlserialize anders herum)



oulbrich
05-03-21, 07:25
Hallo,

ich habe eine "schlechte" DB2 Datei. In einem Datensatz stehen 4 x 3 Felder die ich untereinander per SQL darstellen möchte. Siehe Bsp.


<tbody>















Kdnr
Ans1
Name1
Ort1

An2
Name2
Ort2

Ans3
Name3
Ort3



110
10
Markus
Muenchen

20
Juergen
Koe¶ln

30
Peter
Berlin


















Kdnr
Ans
Name
Ort











110
10
Markus
Muenchen











110
20
Juergen
Koeln











110
30
Peter
Berling










</tbody>

Gibt es da etwas in SQL.

Gruss Olaf

Robi
05-03-21, 07:31
select f1, f2, f3, f4 from datei where ...
union all
select f1, f5, f6, f7 from datei where ...
union all
select ...

order by 1

oulbrich
05-03-21, 07:44
Danke Robi für die schnelle Antwort.

Ahoy
05-03-21, 07:46
Das wäre auch ne Möglichkeit:

with
test_data(kdnr, ans1, name1, ort1, ans2, name2, ort2, ans3, name3, ort3) as (
values
(110, 10, 'Markus', 'München', 20, 'Jürgen', 'Köln', 30, 'Peter', 'Berlin'),
(120, 20, 'Stefan', 'Augsburg', 0, '', '', 0, '', '')
),

test_data_tab(kdnr, ans, name, ort) as (
select
tab_data.*
from
test_data

cross join lateral(
values
(kdnr, ans1, name1, ort1),
(kdnr, ans2, name2, ort2),
(kdnr, ans3, name3, ort3)
) as tab_data(kdnr, ans, name, ort)
where
ans <> 0
)

select * from test_data_tab

Fuerchau
05-03-21, 08:35
Dann mach mal deinen Crossjoin mit 1000 Zeilen, das ergibt 1 Millionen Zugriffe.
Der Union macht da nur 4000 Zugriffe.

Den "lateral" nehme ich häufig als Ersatz für skalare Subselects, wenn man mehr als 1 Feld benötigt und dies nicht per Join erledigt werden kann, z.B. mit "order by xxx desc fetch first 1 rows only".
Funktioniert sehr gut bei einer terminierten Preisfindung.

Ahoy
05-03-21, 09:27
Wieso das? Bei einem cross join lateral wird jede Zeile mit den Zeilen der jeweiligen Values List verbunden, damit gibt es also nur 1000 Zugriffe anstatt 4000.

Fuerchau
05-03-21, 21:45
Ja, man muss sich nur mal das Konstrukt genauer ansehen:



values
(kdnr, ans1, name1, ort1),
(kdnr, ans2, name2, ort2),
(kdnr, ans3, name3, ort3)
) as tab_data(kdnr, ans, name, ort)


Ich habe lateral ähnlich gesehen wie beim Join mit einer anderen Tabelle.
Hier bezieht sich Values() direkt auf die From-Table. Das hatte ich so genau nicht gesehen.
Diese Variante kannte ich noch nicht, hilft mir aber nun auch bei anderen ähnlichen Konstrukten, da es in ERP's durchaus ähnliche Strukturen gibt.

Da hier kein zusätzlicher Zugriff erfolgt, könnte diese Abfrage sogar schneller als der Union sein, da hier direkt verarbeitet werden kann und nicht erst alles gelesen werden muss.

BenderD
06-03-21, 06:29
Ja, man muss sich nur mal das Konstrukt genauer ansehen:



values
(kdnr, ans1, name1, ort1),
(kdnr, ans2, name2, ort2),
(kdnr, ans3, name3, ort3)
) as tab_data(kdnr, ans, name, ort)


Ich habe lateral ähnlich gesehen wie beim Join mit einer anderen Tabelle.
Hier bezieht sich Values() direkt auf die From-Table. Das hatte ich so genau nicht gesehen.
Diese Variante kannte ich noch nicht, hilft mir aber nun auch bei anderen ähnlichen Konstrukten, da es in ERP's durchaus ähnliche Strukturen gibt.

Da hier kein zusätzlicher Zugriff erfolgt, könnte diese Abfrage sogar schneller als der Union sein, da hier direkt verarbeitet werden kann und nicht erst alles gelesen werden muss.

... it depends on optimizer!
Ein SQL Statement beschreibt (laut SQL Standard) ein ResultSet und keine Zugriffsmethode und das ist gerade der Vorteil gegenüber ISAM - was der Optimizer daraus macht, sagt dann etwas über die Qualität der Datenbank Implementierung aus.

D*B

Fuerchau
10-03-21, 12:24
So, nun habe ich das mal selber mit XPPS-Tabellen ausprobiert. Da gibt es haufenweise Tabellen, die solche Strukturen haben.
Laut Visual Explain wird für die Values-List kein IO benötigt und der nested loop join benötigt kaum messbare Zeit.
Die Tabelle hat ca. 10 Mio Zeilen und die Ergebnisse kommen sauschnell.