Tabellen vereinigen mit UNION

DiegoP

Neuer Benutzer
Beiträge
2
Hallo,

ich stehe hier gerade vor einem Problem, wonach ich gegoogelt habe, eine Lösung gefunden und auf mein Problem angewendet habe, leider ist das Ergebnis nicht das erwartete.

Ich habe hier verschiedene Views aus Tabellen erstellt.
In einem View "Jahre" stehen nur Jahre von 2007 - 2013 drin, also:
Code:
|Jahr|
|2007|
|2008|
|2009|
|2010|
|2011|
|2012|
|2013|

Dann habe ich 3 weitere Tabellen, welche jeweils als Spalte ein Jahr beinhalten sowie einen bestimmten Wert.
Diese Tabellen müssen aber nicht alle Jahre beinhalten, z.B:
Code:
"tab1"
|Jahr|Wert_1|
|2007|   100|
|2009|   120|
|2011|   130|

und

Code:
"tab2"
|Jahr|Wert_2|
|2007|   110|
|2008|    20|
|2009|   130|
|2011|   140|
|2012|   120|

und

Code:
"tab3"
|Jahr|Wert_3|
|2008|   200|
|2009|   220|
|2010|   150|
|2013|   200|

Ich möchte nun alle 4 Tabellen miteinander verbinden, d.h. am Ende eine Tabelle haben mit diesem Format:
Code:
|Jahr|Wert_1|Wert_2|Wert_3|
|2007|   100|   110|    - |
|2008|    - |    20|   200|
|2009|   120|   130|   220|
|2010|    - |    - |   150|
|2011|   130|   140|    - |
|2012|    - |   120|    - |
|2013|    - |    - |   200|

Dafür habe ich mir ein Query überlegt, welches folgendermaßen aussieht:
Code:
SELECT
j.Jahr AS 'Jahr',
t1.Wert_1 AS 'Wert_1',
'' AS 'Wert_2',
'' AS 'Wert_3'
FROM Jahre j
LEFT JOIN
tab1 t1
ON j.Jahr = t1.Jahr

UNION

SELECT
j.Jahr AS 'Jahr',
'' AS 'Wert_1',
t2.Wert_2 AS 'Wert_2',
'' AS 'Wert_3'
FROM Jahre j
LEFT JOIN
tab2 t2
ON j.Jahr = t2.Jahr 

UNION

SELECT
j.Jahr AS 'Jahr',
'' AS 'Wert_1',
'' AS 'Wert_2',
t3.Wert_3 AS 'Wert_3'
FROM Jahre j
LEFT JOIN
tab2 t3
ON j.Jahr = t3.Jahr

Ich habe es auch schon mit UNION ALL versucht, aber die Spalten werden nicht "nebeneinander" gestellt, sondern immer sowas:

Code:
|Jahr|Wert_1|Wert_2|Wert_3|
|2007|   100|      |      |
|2008|      |      |      |
|2009|   120|      |      |
|2010|      |      |      |
|2011|   130|      |      |
|2012|      |      |      |
|2013|      |      |      |
|2007|      |   110|      |
|2008|      |    20|      |
|2009|      |   130|      |
|2010|      |      |      |
|2011|      |   140|      |
|2012|      |   120|      |
|2013|      |      |      |
|2007|      |      |      |
|2008|      |      |   200|
|2009|      |      |   220|
|2010|      |      |   150|
|2011|      |      |      |
|2012|      |      |      |
|2013|      |      |   200|

Weiss jemand, woran das liegen könnte?
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.731
Hallo,

ich stehe hier gerade vor einem Problem, wonach ich gegoogelt habe, eine Lösung gefunden und auf mein Problem angewendet habe, leider ist das Ergebnis nicht das erwartete.


Ich möchte nun alle 4 Tabellen miteinander verbinden, d.h. am Ende eine Tabelle haben mit diesem Format:
Code:
|Jahr|Wert_1|Wert_2|Wert_3|
|2007|   100|   110|    - |
|2008|    - |    20|   200|
|2009|   120|   130|   220|
|2010|    - |    - |   150|
|2011|   130|   140|    - |
|2012|    - |   120|    - |
|2013|    - |    - |   200|

Du bist nah dran. Über das Resultat, was Du bekommst, aggregierst Du. Du summierst die Werte und gruppierst nach Jahr. Das schaffst Du.
Einzig, was noch knifflig werden könnte, ist, daß Deine Werte offenbar vom falschen Datentyp sind. Du wirst Dich, falls dem so ist, mit dem CASTen befreunden müssen.
 

DiegoP

Neuer Benutzer
Beiträge
2
Ah danke sehr!
Es funktioniert mit GROUP BY und SUM.
Zwar umständlich, aber es klappt :)

Jetzt noch eine weitere Frage:
Ich habe nun viele Tabellen mit der gleichen Struktur, kann ich die Einträge aller Tabellen irgendwie als eine "lange" zusammenführen?
 

Hubertus

Fleissiger Benutzer
Beiträge
57
So geht's auch:

Code:
SELECT
j.Jahr AS 'Jahr',
t1.Wert_1 AS 'Wert_1',
t2.Wert_2 AS 'Wert_2',
t3.Wert_3 AS 'Wert_3'
FROM Jahre j
LEFT JOIN
tab1 t1
ON j.Jahr = t1.Jahr
LEFT JOIN
tab2 t2
ON j.Jahr = t2.Jahr
LEFT JOIN
tab3 t3
ON j.Jahr = t3.Jahr
ORDER BY Jahr

Die Frage
kann ich die Einträge aller Tabellen irgendwie als eine "lange" zusammenführen?
verstehe ich nicht.
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.731
Ah danke sehr!
Es funktioniert mit GROUP BY und SUM.
Zwar umständlich, aber es klappt :)

Jetzt noch eine weitere Frage:
Ich habe nun viele Tabellen mit der gleichen Struktur, kann ich die Einträge aller Tabellen irgendwie als eine "lange" zusammenführen?

Warum? Das klingt nach einem falschen Design, sonst würdest Du nicht so fragen.

Wenn man es richtig macht, kann man beliebig viele Tabellen gleicher Struktur haben und nur eine abfragen und dennoch das Resultat aus allen bekommen: nennt sich Table Partitioning. Lohnt sich erst ab 1-10 Millionen Zeilen pro Kindtabelle und geht so:

Code:
test=# create table master_table (id serial primary key, val int);  
CREATE TABLE  
Time: 6,187 ms  
test=*# create table p0 (check(val % 3 = 0)) inherits (master_table);
CREATE TABLE  
Time: 1,158 ms  
test=*# create table p1 (check(val % 3 = 1)) inherits (master_table);
CREATE TABLE  
Time: 1,269 ms  
test=*# create table p2 (check(val % 3 = 2)) inherits (master_table);
CREATE TABLE
Time: 1,118 ms

An der Stelle müßte nun noch ein Trigger erstellt werden, der bei Inserts in die master_tabelle den Insert in die richtige p[012] - Tabelle leiten, ich mache es mal händisch:

Code:
test=*# insert into p0 (val) values (3);
INSERT 0 1
Time: 0,418 ms
test=*# insert into p0 (val) values (6);
INSERT 0 1
Time: 0,196 ms
test=*# insert into p1 (val) values (7);
INSERT 0 1
Time: 0,381 ms
test=*#
test=*#
test=*# select * from master_table where val % 3 = 0;
id | val
----+-----
  1 |  3
  2 |  6
(2 rows)
Wie man sieht, inserte ich in die pX - Tabellen, frage aber nur die master_table ab. Aufgrund der Constraints werden auch nur die (immer) die master_tabelle und die korrekte pX - Tabelle abgefragt:

Code:
test=*# explain select * from master_table where val % 3 = 0;
  QUERY PLAN
------------------------------------------------------------------
Append  (cost=0.00..42.10 rows=12 width=8)
  ->  Seq Scan on master_table  (cost=0.00..0.00 rows=1 width=8)
  Filter: ((val % 3) = 0)
  ->  Seq Scan on p0  (cost=0.00..42.10 rows=11 width=8)
  Filter: ((val % 3) = 0)
(5 rows)

Ein Insert in die falsche pX - Tabelle schlägt natürlich fehl:

Code:
test=*# insert into p2 (val) values (7);
ERROR:  new row for relation "p2" violates check constraint "p2_val_check"
DETAIL:  Failing row contains (4, 7).
Time: 0,303 ms

Du brauchst das in Deinem MySQL jetzt aber nicht nachmachen, das kann das nicht oder nur halb oder so.

Erkläre aber, warum Du so eine Struktur hast, ohne zu wissen, wie man es 'richtig' macht.
 
Oben