SQL,Access: Mehrere Tabellen mit gleicher Struktur bzw. Spalten zusammenführen
Hallo,
ich habe eine zugegebener Weise nicht so tolle Access Datenbank bekommen, aus der ich Daten rausziehen muss. In der DB gibt es Tabellen, die DatenXX heißen. XX steht hierbei für die Kurzform von Jahreszahlen (das sollte wohl der Übersichtlichkeit dienen). Die Tabellen haben ansonsten alle die gleiche Struktur bzw. Spaltenbezeichnungen. Eine Spalte heißt jahrgang und ich benötige nun alle Datensätze, bei denen das Feld "jahrgang" leer ist. Für eine einzelne Tabelle ist das ja recht schnell gemacht, ich benötige die Datensätze nun aber aus allen Tabellen bei denen jahrgang leer. Die entsprechenden Datensätze aus allen Tabellen sollen in der Ausgabe dann einfach untereinander geschrieben werden.
Bei zwei Tabellen würde ich das einfach so machen:
Doch was ist die eleganteste Möglichkeit die Datensätze aus allen Tabellen (Daten00 - Daten99) zusammenzuführen? 98 UNIONs? Da meckert Access garantiert, dass die Abfrage zu komplex ist. Gibt es eine Möglichkeit mit einem Range-Operator oder so zu arbeiten, der mir nicht bekannt ist? Also z. B. SELECT * FROM RANGE Daten$XX (00,99,1) WHERE....
Ich freue mich auf eure Tipps.
Grüße
PSaR04
ich habe eine zugegebener Weise nicht so tolle Access Datenbank bekommen, aus der ich Daten rausziehen muss. In der DB gibt es Tabellen, die DatenXX heißen. XX steht hierbei für die Kurzform von Jahreszahlen (das sollte wohl der Übersichtlichkeit dienen). Die Tabellen haben ansonsten alle die gleiche Struktur bzw. Spaltenbezeichnungen. Eine Spalte heißt jahrgang und ich benötige nun alle Datensätze, bei denen das Feld "jahrgang" leer ist. Für eine einzelne Tabelle ist das ja recht schnell gemacht, ich benötige die Datensätze nun aber aus allen Tabellen bei denen jahrgang leer. Die entsprechenden Datensätze aus allen Tabellen sollen in der Ausgabe dann einfach untereinander geschrieben werden.
Bei zwei Tabellen würde ich das einfach so machen:
SELECT * FROM (SELECT * FROM Daten00 UNION ALL SELECT * FROM Daten01) WHERE jahrgang is null;
Doch was ist die eleganteste Möglichkeit die Datensätze aus allen Tabellen (Daten00 - Daten99) zusammenzuführen? 98 UNIONs? Da meckert Access garantiert, dass die Abfrage zu komplex ist. Gibt es eine Möglichkeit mit einem Range-Operator oder so zu arbeiten, der mir nicht bekannt ist? Also z. B. SELECT * FROM RANGE Daten$XX (00,99,1) WHERE....
Ich freue mich auf eure Tipps.
Grüße
PSaR04
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 242753
Url: https://administrator.de/contentid/242753
Ausgedruckt am: 25.11.2024 um 23:11 Uhr
5 Kommentare
Neuester Kommentar
Hallo PSaR04,
mit VBA hätte ich dafür eine Lösung. Es fasst alle deine gewünschten Daten in einer neu erstellten Tabelle zusammen, und öffnet diese zum Schluss.
Grüße Uwe
mit VBA hätte ich dafür eine Lösung. Es fasst alle deine gewünschten Daten in einer neu erstellten Tabelle zusammen, und öffnet diese zum Schluss.
Sub MergeTablesIntoOne()
Dim rsAll As Recordset, rsCurrent As Recordset, tblName as String, c as integer, i as integer
DoCmd.SetWarnings False
' passende Datensätze aus Daten00 in neue Tabelle schreiben
DoCmd.RunSQL "Select * into DataResult from Daten00 where jahrgang is null"
DoCmd.SetWarnings True
' neue Tabelle öffnen
Set rsAll = CurrentDb.OpenRecordset("Select * From DataResult", dbOpenDynaset)
Set db = CurrentDb
' Für alle passenden Tabellen
For i = 1 To 99
tblName = "Daten" & Right("0" & i, 2)
Set rsCurrent = db.OpenRecordset("Select * From " & tblName & " where jahrgang is null", dbOpenSnapshot)
rsCurrent.MoveFirst
While Not rsCurrent.EOF
rsAll.AddNew
For c = 0 To rsAll.Fields.Count - 1
rsAll.Fields(c).Value = rsCurrent.Fields(c).Value
Next
rsAll.Update
rsCurrent.MoveNext
Wend
Next
' neu erstellte Tabelle anzeigen
DoCmd.OpenTable "DataResult"
End Sub
1. Bei der Deklaration der Recordsets rsAll und rsCurrent musste ich den Datentyp von "Recordset" auf "DAO.Recordset" ändern. Da es sonst zur Fehlermeldung "Typen unverträglich" kam.
OK, dann handelt es sich vermultich um eine ältere Access Datenbank. In neueren ist ADO Standard.Anhand der doch relativ aufwendigen Lösung gehe ich dann davon aus, dass sich die gewünschte Abfrage nicht einfacher realisieren lässt (etwa über einen mir unbekannten Operater oder ähnlichem, wie im ersten Post von
Wart mal ab vielleicht hat der @Biber da eventuell noch eine Lösung für eine reine SQL Abfrage.Grüße Uwe
Moin PSaR04 und colinardo,
um die Zweifel auszuräumen:
- es existiert weder in Access-SQL noch einem anderem SQL-Dialekt etwas wie "Mach mir einen UNION über Tabelle 1...n"
- wie PSaR04 schon richtig vermutete - Access würde bei 99 Tabellen in einer Query auch bedauernd abwinken, da bei 32 offenen Tabellen in einer Query Schicht ist (Okay, ist an dieser Stelle mal kein Vorwurf an die PraktikantInnen. Wenn mehr als 32 Tabellen in einer Query verbaut werden müssen, dann ist das Datenbankdesign marode, so wie ja auch in dieser "Ich mach ma' 100 Tabellen, weil ich 100 Jahre verwalten will"-Musterlösung).
Einziger Verbesserungsvorschlag, den ich zum Skript anbringen würde:
Ich würde sicherheitshalber ein Feld mehr ins Resultset übernehmen, damit ich weiss, aus welcher Tabelle der Satz stammt.
Also statt
etwa so
Falls die Abfragen auf die 99 Tabellen noch auf andere Fragestellungen modifiziert werden sollen:
Dann würde ich die Daten aus den Tabellen 1..99 nicht nur jetzt einmalig in einen Resultset schaufeln, sondern gleich- wenn ich eh' alle Tabellen durchwackeln muss- den ganzen Quatsch in eine neue Tabelle schreiben. Mit allen Sätzen, ohne einschränkendes WHERE.
Und eben mit einem Zusatzfeld, in dem der Quelltabellenname steht.
Grüße
Biber
um die Zweifel auszuräumen:
- es existiert weder in Access-SQL noch einem anderem SQL-Dialekt etwas wie "Mach mir einen UNION über Tabelle 1...n"
- wie PSaR04 schon richtig vermutete - Access würde bei 99 Tabellen in einer Query auch bedauernd abwinken, da bei 32 offenen Tabellen in einer Query Schicht ist (Okay, ist an dieser Stelle mal kein Vorwurf an die PraktikantInnen. Wenn mehr als 32 Tabellen in einer Query verbaut werden müssen, dann ist das Datenbankdesign marode, so wie ja auch in dieser "Ich mach ma' 100 Tabellen, weil ich 100 Jahre verwalten will"-Musterlösung).
Einziger Verbesserungsvorschlag, den ich zum Skript anbringen würde:
Ich würde sicherheitshalber ein Feld mehr ins Resultset übernehmen, damit ich weiss, aus welcher Tabelle der Satz stammt.
Also statt
Set rsCurrent = db.OpenRecordset("Select * From " & tblName & " where jahrgang is null",
etwa so
Set rsCurrent = db.OpenRecordset("Select ' " & tblname & " ' as Tbname, t.* From " & tblName &" as t where jahrgang is null",
Falls die Abfragen auf die 99 Tabellen noch auf andere Fragestellungen modifiziert werden sollen:
Dann würde ich die Daten aus den Tabellen 1..99 nicht nur jetzt einmalig in einen Resultset schaufeln, sondern gleich- wenn ich eh' alle Tabellen durchwackeln muss- den ganzen Quatsch in eine neue Tabelle schreiben. Mit allen Sätzen, ohne einschränkendes WHERE.
Und eben mit einem Zusatzfeld, in dem der Quelltabellenname steht.
Grüße
Biber