2009-07-01 7 views
1

ich von einem vertikalen db Layout wie diese Daten übertragen will:Wie kann ich effizient Daten von einem vertikalen databaselayout Übertragung auf einen horizontalen

 
--------------------- 
| ID | Type | Value | 
--------------------- 
| 1 | 10 | 111 | 
--------------------- 
| 1 | 14 | 222 | 
--------------------- 
| 2 | 10 | 333 | 
--------------------- 
| 2 | 25 | 444 | 
--------------------- 

auf einen horizontalen:

 
--------------------------------- 
| ID | Type10 | Type14 | Type25 | 
--------------------------------- 
| 1 | 111 | 222 |  | 
--------------------------------- 
| 2 | 333 |  | 444 | 
--------------------------------- 

Erstellen Das Layout ist kein Problem, aber die Datenbank ist ziemlich groß mit Millionen von Einträgen und Abfragen werden abgebrochen, wenn sie zu lange dauern.

Wie kann dies effizient durchgeführt werden (damit die Abfrage nicht abgebrochen wird).

+0

Ich glaube, das ist allgemein bekannt als Schwenk – dplante

Antwort

0
with t as 
(
select 1 as ID, 10 as type, 111 as Value from dual 
union 
select 1, 14, 222 from dual 
union 
select 2, 10, 333 from dual 
union 
select 2, 25, 444 from dual 
) 
select ID, 
max(case when type = 10 then Value else null end) as Type10, 
max(case when type = 14 then Value else null end) as Type14, 
max(case when type = 25 then Value else null end) as Type25 
from t 
group by id 

Gibt zurück, was Sie wollen, und ich denke, es ist der bessere Weg. Beachten Sie, dass die Max-Funktion nur hier ist, um die Gruppierung nach Klausel auszuführen, jede Gruppenfunktion kann hier verwendet werden (wie Summe, Min ...)

+0

Funktioniert gut, danke. – OliverS

0

Zerlegen Sie es in kleinere Stücke und wickeln Sie das Ganze nicht in einer einzigen Transaktion ein. Erstellen Sie zunächst die Tabelle, und führen Sie dann Gruppen von Einfügungen aus der alten Tabelle in die neue Tabelle ein. B. nach Größe der ID einfügen, so klein, dass es das Protokoll der Datenbank nicht überlastet und zu lange dauert.

0

Die vertikale Tabelle - auch bekannt als Entity-Attribut-Value Anti-Pattern - wird immer ein Problem, manchmal sehr kurz nachdem es in die Praxis umgesetzt wurde. Wenn Sie dies noch nicht getan haben, schauen Sie sich an, was Joe Celko über diese Taktik zu sagen hat, und Sie werden noch mehr Beweise dafür sehen, wie problematisch dieser Ansatz ist. Ich höre hier auf, denn Sie sind die kluge Person, die wusste, dass Sie zu dieser Seite kommen sollten, und nicht die schuldige, aber gut gemeinte Partei, die die EAV-Tabelle in Ihrer Datenbank verübt hat.

Die Optionen für den Umgang mit diesem Tabellentyp sind nicht schön, und wie Sie gesagt haben, werden sie immer schlechter, je mehr Daten für Produktionsabfragen benötigt werden.

  1. Erstellen Sie eine deklarierte globale temporäre Tabelle (DGTT), die nicht angemeldet ist, und erhält festgeschriebene Zeilen, und es verwenden, um die horizontale Version der EAV Tabelleninhalte zu inszenieren. DGTTs sind gut für diese Art von Datenschaufeln, da sie keinen Protokollierungsaufwand verursachen.

  2. Verwenden Sie die traditionellen CASE- und MAX() - Gruppierungen, wie in der vorherigen Empfehlung gezeigt. Das Problem besteht darin, dass sich die Abfrage jedes Mal ändert, wenn ein neuer TYPE in Ihre EAV-Tabelle eingefügt wird.

  3. Verwenden Sie die SQL-XML-Veröffentlichungsfunktionen von DB2, um die vertikalen Daten in XML zu konvertieren. Hier ist ein Beispiel, das mit den Tabellen- und Spaltennamen arbeiten Sie zur Verfügung gestellten:


WITH t(id, type, value) as (
VALUES (1,10,111), (1,14,222), (2,10,333), (2,25,444) 
) 

SELECT 
XMLSERIALIZE(CONTENT 
XMLELEMENT(NAME "outer", 
    XMLATTRIBUTES(id AS "id"), 
     XMLAGG(XMLELEMENT(NAME attr , 
      XMLATTRIBUTES(type as "typeid"), value) ORDER BY type) 
) AS VARCHAR(1024) 
) 
FROM t as t group by id; 

Der Vorteil des SQL-XML-Ansatzes besteht darin, dass neue von der EAV-Tabelle behandelten Werte nicht Erfordert ein Neuschreiben der SQL, die die Werte umschreibt.

Verwandte Themen