2010-12-02 2 views
2

Ok, für das Beispiel habe ich drei Tabellen:Wie können Sie nicht verwandte Tabellen zusammenführen, aber nach einem gemeinsamen Spaltentyp sortieren?

**Table A** 
id (serial) 
timestamp (timestamp) 
value1 (double) 
value2 (double) 

**Table B** 
id (serial) 
timestamp (timestamp) 
text1 (text) 
char1 (character) 

**Table C** 
id (serial) 
timestamp (timestamp) 
int1 (int) 
int2 (int) 

Die ID-Felder für jede Tabelle eindeutig sind, und als Primärschlüssel dienen. Zeitstempel werden eingegeben, wenn Zeilen in der Tabelle platziert werden, aber nicht mit den anderen Tabellen verbunden sind. In jede Tabelle können Zeilen zu unterschiedlichen Zeiten eingefügt werden.

Was ich will ist eine Ansicht oder ein einzelnes Dataset, das alle Datensätze aus jeder der Tabellen enthält, sortiert nach Zeitstempel.

In diesem Beispiel würde dies bedeuten, dass der Datensatz die folgenden Spalten haben würde:

**Output Table** 
timestamp (timestamp) 
value1 (double) 
value2 (double) 
text1 (text) 
char1 (character) 
int1 (int) 
int2 (int) 

Ich verstehe, dass für jede Zeile dieses resultierenden Datensatz 4 der Spalten leer wäre. Allerdings muss ich in der Lage sein, die Daten aus allen Tabellen sortiert in der Reihenfolge der Zeitstempel (und für einen bestimmten Zeitstempel Bereich) zu sehen

Ich habe Gewerkschaften angesehen, aber sie wollen gemeinsame Spalte Datentypen, so dass didn ' t fit. Joins schien eine Verbindung zwischen Spalten in einer Tabelle und anderen zu benötigen, so dass nicht passt.

Ich muss nur eine Tabelle erstellen, die aus allen Spalten der drei Tabellen besteht, mit einem einzigen (Zeitstempel) als gemeinsame Sortierspalte.

Was wäre der beste Weg, um dies zu tun? Ist das in SQL überhaupt möglich?

Meine ursprüngliche Idee war, die Daten aus jeder Tabelle getrennt in ein Array (PHP/C++) zu extrahieren, dann eine Sortierung dort durchzuführen, aber das scheint unglaublich langsam zu sein, also hoffte ich auf eine viel schnellere SQL-Lösung.

Hinweis: Die Tabellen können jeweils viele tausend Einträge enthalten. Meine Datenbank ist in PostgreSQL, wenn es relevant ist.

Antwort

2

folgenden Code tut, was Sie brauchen, und kümmert sich auch um verschiedene Sortierungen zwischen den Spalten. Die Lösung ist MySQL-spezifisch (aufgrund der Verwendung der CAST-Funktion und kollationsbezogener Probleme).

SELECT * FROM (
SELECT 
    `timestamp`, 
    CAST(`value1` AS CHAR) AS `value1`, 
    CAST(`value2` AS CHAR) AS `value2`, 
    CAST(NULL AS CHAR) AS `text1`, 
    CAST(NULL AS CHAR) AS `char1`, 
    CAST(NULL AS SIGNED) AS `int1`, 
    CAST(NULL AS SIGNED) AS `int2` 
FROM `table_a` 
UNION 
SELECT 
    `timestamp`, 
    CAST(NULL AS CHAR) AS `value1`, 
    CAST(NULL AS CHAR) AS `value2`, 
    CAST(`text1` AS CHAR) AS `text1`, 
    CAST(`char1` AS CHAR) AS `char1`, 
    CAST(NULL AS SIGNED) AS `int1`, 
    CAST(NULL AS SIGNED) AS `int2` 
FROM `table_b` 
UNION 
SELECT 
    `timestamp`, 
    CAST(NULL AS CHAR) AS `value1`, 
    CAST(NULL AS CHAR) AS `value2`, 
    CAST(NULL AS CHAR) AS `text1`, 
    CAST(NULL AS CHAR) AS `char1`, 
    CAST(`int1` AS SIGNED) AS `int1`, 
    CAST(`int2` AS SIGNED) AS `int2` 
FROM `table_c`) `table_all` 
ORDER BY `timestamp` 

Auch die Tatsache, dass Sie können es tun, bedeutet nicht, dass Sie sollte es tun. Versuchen Sie besser, Ihre Daten neu anzuordnen, (de) zu normalisieren, sonst könnten Sie immer wieder auf ähnliche Probleme stoßen. Das Sortieren vieler Zeilen im UNION-Ergebnissatz ist alles andere als effizient ...

+0

Leider werden die Daten von externen Anwendungen generiert, die ich nicht kontrollieren kann, und ich muss mich nur mit ihrer mangelnden Vorsichtigkeit (wie immer) auseinandersetzen. :( – Dave

2

Sie können die fehlenden Spalten manuell mit Union hinzufügen:

SELECT * FROM(
    SELECT timestamp, value1, value2, null as text1, null as char1, null as int1, null as int2 FROM tableA 
    union all 
    SELECT timestamp, null, null, text1, char1, null, null FROM tableB 
    union all 
    SELECT timestamp, null, null, null, null, int1, int2 FROM tableC 
) ORDER BY timestamp; 
1

Verwenden Sie eine Union, aber fügen Sie zusätzliche Spalten hinzu, so dass jede zusammengesetzte Tabelle dieselbe Signatur hat.

Select id, timestamp, value1, value2, 
    Cast(null as text) text1, 
    Cast(null as char(1)) char1, 
    Cast(null as int) int1, 
    Cast(null as int) int2 From Table1 
Union 
Select id, timestamp, 
    Cast(null as double) value1, 
    Cast(null as double) value2, 
    text1, car1, 
    Cast(null as int) int1, 
    Cast(null as int) int2 From Table2 
Union 
Select id, timestamp, 
    Cast(null as double) value1, 
    Cast(null as double) value2, 
    Cast(null as text) text1, 
    Cast(null as char(1)) char1, 
    int1, int2 From Table3 
Order By Timestamp 
0

Eine vollständige äußere Verknüpfung auf Zeitstempel als die union Beispiele wie gut funktionieren würde. Dunno über die Leistung, aber die Abfrage ist kürzer.

+0

Die timstamps von jeder Tabelle stimmen nicht überein, also würde die äußere Verknüpfung nicht funktionieren, würde es? – Dave

+0

Eine volle äußere würde, deshalb wählte ich es aus. – Donnie

Verwandte Themen