Frage von nstuebner, 48

SQL Abfrage in variabler Tabelle?

Ich habe eine Frage zu einer SQL-Abfrage an einen SQLEXPRESS Server (2008)

Ich habe eine Tabelle 'Zähler' mit folgendem Inhalt:

ID --- Name

  • xc8f9g3 --- Zähler1
  • yoks8w --- Zähler2
  • 9sjwna --- Zähler3

dazu habe ich noch mehrere Tabellen, die folgendermaßen heißen:

  • Daten_xc8f9g3
  • Daten_yoks8w
  • Daten_9sjwna

In diesen Tabellen stehen die erfassten Werte "ID", "Zeitpunkt" und "Zählerstand".

Ich möchte nun, dass ich mit einer einzigen Abfrage die Zählernamen, den letzten Zeitpunkt und den letzten Zählerstand erhalte:

  • Zähler1 --- 09.12.2015 06:21:00 --- 12345,0
  • Zähler2 --- 09.12.2015 06:35:00 --- 23456,0
  • Zähler3 --- 09.12.2015 08:12:00 --- 34567,0

Meine Abfrage sollte dabei so ungefähr aussehen:

SELECT ID, Name, (SELECT Zeitpunkt FROM ??? WHERE ID=(SELECT MAX(ID) FROM ???)) AS Zeitpunkt, (SELECT Zählerstand FROM ??? WHERE ID=(SELECT MAX(ID) FROM ???)) AS Zählerstand FROM Zähler ORDER BY Name ASC

Ich möchte an Stelle der ??? jetzt aber die Tabelle "Daten_" + der ausgelesenen ID zu stehen haben.

Auf die Datenbank habe ich nur lesenden Zugriff und kann/möchte die Sruktur nicht ändern.

Antwort
von daCypher, 28

Das geht nichtmal mit Stored Procedures so wie du dir wünscht. Ich würde dir empfehlen, dass du die ganzen "Daten_xyz123" Tabellen in eine einzelne Tabelle zusammenführst, in der halt die Daten aus den einzelnen Tabellen und eine neue Spalte mit der ZählerID drinsteht. Das lässt sich mit einem SP bewerkstelligen.

Erstelle eine Tabelle mit dem Namen "Daten_Gesamt" und den Feldern ZählerID, ID, Zeitpunkt, Zählerstand

Wenn ich keinen Fehler gemacht habe, müsstest du die Tabelle mit dieser Prozedur füllen können (der hat die einzelnen Zeilen auseinandergerissen. Musst die halt alle reinkopieren):

-- temporäre Tabelle erstellen
DECLARE @tblNames AS TABLE(tblNr int, tblName nVarChar(50));
-- temporäre Tabelle mit Tabellennamen füllen
INSERT INTO @tblNames(tblNr, tblName)
SELECT ROW_NUMBER() OVER (ORDER BY name) AS RowNr, name 
FROM sys.objects 
WHERE type = N'U' AND name like N'Daten_%';
-- Steuervariablen erstellen
DECLARE @i int = 1;
DECLARE @SQL nvarchar(max);
DECLARE @maxRow int;
DECLARE @ZaehlerID nvarchar(10);
-- Schleife über alle gefundenen Tabellen. Die Daten werden in die Tabelle "Daten_Gesamt" geschrieben.
SET @maxRow = (SELECT MAX(tblNr) AS MaxRowNr FROM @tblNames)
WHILE @i <= @maxRow
BEGIN
SET @ZaehlerID = SUBSTRING((SELECT tblName FROM @tblNames WHERE tblNr = @i), 7, 10)
SET @SQL = N'
INSERT INTO Daten_Gesamt(ZählerID, ID, Zeitpunkt, Zählerstand)
SELECT N''' + @ZaehlerID + N''' AS ZählerID, ID, Zeitpunkt, Zählerstand
FROM Daten_' + @ZaehlerID + N';';
EXEC sp_sqlexec @SQL;
END
Kommentar von nstuebner ,

Aber brauche ich zum Erzeugen der temporären Zwischentabelle nicht Schreibrechte? Ich habe leider nur einen lesenden Zugriff.

Kommentar von daCypher ,

Für diese Daten_Gesamt Tabelle brauchst du Schreibrechte. Ob es reicht, wenn du statt einer "echten" Tabelle auch eine Tabellenvariable erzeugst, wo die Daten reinkommen (also so, wie die @tblNames in der Prozedur), kann ich dir nicht sagen. Hab noch nie mit eingeschränkten Rechten auf dem SQLServer gearbeitet.

Kommentar von maximilianus7 ,

geht da nicht #Daten_Gesamt als name, damit dies auch eine temporäre tabelle ist? http://www.sqlservercurry.com/2013/11/working-with-temporary-objects-in-sql_30.h...

Kommentar von daCypher ,

Könnte man auch probieren. Ich denke aber nicht, dass es ohne Schreibrechte geht, weil eine Tabelle mit Raute auch auf dem Server erstellt wird (wird aber automatisch wieder gelöscht, wenn die Session geschlossen wird)

Antwort
von DieAndwoord, 5

habe grade kein Studio zurhand.

wenn ich es richtig verstanden habe hast du nur die drei Tabellen

dann würde es so gehen

select top 1 Zähler1, Datum, Stand from Zähler order by Datum desc 

union all

select top 1 Zähler1, Datum, Stand from Zähler order by Datum desc

union all

select top 1 Zähler1, Datum, Stand from Zähler order by Datum desc

alternativ könntest du auch ein where datum = ( select max(datum) from Zähler) nehmen, musst du schauen was schneller ist.

Antwort
von Suboptimierer, 24

Funktioniert "...Zeitpunkt FROM 'Daten_' || Zähler.ID..." nicht?

Probier mal, die Tabelle als Zeichenkette zusammen zu setzen, von der du lesen willst.

1. Schritt: 'Daten_xc8f9g3'
2. Schritt: 'Daten_' || 'xc8f9g3'
3. Schritt: 'Daten_' || Zähler.ID

Kommentar von Suboptimierer ,

Such nach einer Verkettenfunktion in deiner SQL. Es gibt u. a. concat und +.

Antwort
von Seanna, 34

Hast du dich mal mit JOINS beschäftigt? Die wären da hilfreich.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten