[MySQL] Abfrage über mehrere Tabellen, variable Tabellenzahl,

Andre_Java

Mitglied
Ich habe für jeden Monat eine Tabelle und zeichne darin Meßwerte auf. Jetzt kann es sein, dass ich alle Werte von Januar bis März auslesen möchte.

Die Tabellen sehen so aus:

Januar:
Code:
Wert, Zeit
33, 1001
32, 1002
41, 1003

Februar
Code:
Wert, Zeit
31, 1004
33, 1005
33, 1006

In der PHP-Visualisierung gebe ich dann vor, dass ich die Werte im Zeitraum von z.B. 1002 bis 1006 haben möchte. Es kann aber auch sein, dass die Abfrage über mehrere Monate gewünscht ist. Dazu kommt, dass die Werte anhand der Zeit geordnert sein müssen.

Gibt es einen dynamischen Befehl, der das kann? Zwei Tabelle hätte ich mit UNION so verknüpft:

Code:
SELECT Wert, Zeit
FROM Januar
WHERE Zeit >=1002
UNION
SELECT Wert, Zeit
FROM Februar
WHERE Zeit <=1006
ORDER BY Zeit
 
Zuletzt bearbeitet:
Mach und Subquery mit dem UNION und daruaf dann die Bedinung
SQL:
SELECT
	*
FROM
	(
		SELECT 
			Wert, 
			Zeit
		FROM 
			Januar
		UNION SELECT
			Wert,
			Zeit
		FROM 
			Februar
	) AS myData
WHERE 
	Zeit BETWEEN 1002 AND 1006
ORDER 
	BY Zeit
 
Zuletzt bearbeitet von einem Moderator:
Das sieht schon etwas übersichtlicher aus, yaslaw. Ich müsste dann nur in PHP bestimmen, welche Monate in meiner SQL-Abfrage enthalten sein müssen.

Ich hatte vorher alles in einer Tabelle, nur das Löschen und vorallem das Optimieren nach dem Löschen eines Monats hat sehr lange gedauert. So kann ich Monatsweise alte Daten mit "Truncate" schnell freigeben. Das soll ein Speicher für ein Jahr werden. Pro 24h werden etwa 1,5 GB Daten abgelegt.

Jetzt wird es noch etwas komplizierter: Ich möchte für eine erste Übersicht nur jeden 4. Wert anzeigen. Mit nachfolgendem SQL-Befehl funktioniert es aber schon:

Code:
SELECT
    *
FROM
    (
        SELECT 
            Wert, 
            Zeit
        FROM 
            (SELECT @rownum:=0) AS vars, Februar
        UNION SELECT
            Wert,
            Zeit
        FROM 
            (SELECT @rownum:=0) AS vars, Maerz
    ) AS myData
WHERE 
    Zeit BETWEEN 1002 AND 1015 AND MOD((@rownum := @rownum+1), 4) = 0

ORDER 
    BY Zeit

Geht es vielleicht noch handlicher?
 
Du hast jetzt @rownum 2 mal defineiert
Nimm den SELECT @rownum ins obere SQL
SQL:
SELECT
    *
FROM
    (SELECT @rownum:=0) AS vars, 
    (
        SELECT 
            Wert, 
            Zeit
        FROM 
            Februar
        UNION SELECT
            Wert,
            Zeit
        FROM 
            Maerz
    ) AS myData
WHERE 
    Zeit BETWEEN 1002 AND 1015 
    AND MOD((@rownum := @rownum+1), 4) = 0
ORDER 
    BY Zeit
 
Zuletzt bearbeitet von einem Moderator:
Das sieht bezüglich der Übersicht sehr gut aus. Leider wird eine Abfrage über zwei Tabellen sehr langsam.

Während folgende Abfrage nur wenige Millisekunden dauert:
SQL:
SELECT 
  Kanal1, 
  timestamp
FROM 
  Februar
WHERE 
 timestamp BETWEEN 1298867639000 AND 1298877639000
LIMIT 0,30

Dauert diese Abfrage über zwei Tabelle schon so lange, dass ich nach 5 Minuten abbreche:
SQL:
SELECT 
  Kanal1, 
  timestamp
FROM 
  Februar
UNION SELECT
  Kanal1,
  timestamp
FROM 
  Maerz
WHERE 
 timestamp BETWEEN 1298867639000 AND 1298877639000
LIMIT 0,30

Habe ich einen Fehler gemacht oder dauert es einfach so lange? Alles in eine Tabelle zu schreiben geht leider nicht, da ich sonst für das Löschen wieder viel zu lange brauche. Über beide Tabellen wurde "timestamp" als index definiert.
 
Zuletzt bearbeitet von einem Moderator:
So wie ich es habe, werden zuerst alle Daten zusammengenommen und dann gefiltert.
In deinem 2ten Versuch werden nur die Daten vom Maerz gefiltert. Das WHERE gehört zum SELECT und nicht zur Gesammtmenge

Wenn du das SQL aber im PHP erstellst, kannst ud dein BETWEEN auch in die einzelnen Queries schreiben

SQL:
SELECT 
  Kanal1, 
  timestamp
FROM 
  Februar
WHERE 
 timestamp BETWEEN 1298867639000 AND 1298877639000
UNION SELECT
  Kanal1,
  timestamp
FROM 
  Maerz
WHERE 
 timestamp BETWEEN 1298867639000 AND 1298877639000
LIMIT 0,30
 
Zuletzt bearbeitet von einem Moderator:
Danke, damit komme ich auf ca. 5s für die Abfrage. Wie kann ich das jetzt nur wieder mit dem Modulo kombinieren ohne das es langsam wird?
 
Das mit dem Modulo, um jede x-te Zeile auszulassen hast du mir in Thread-Antwort Nr.#5 gezeigt:

SQL:
AND MOD((@rownum := @rownum+1), 4) = 0

Ich habe mir jetzt eine Abfrage zusammengebastelt, die ausreichend schnell zu sein scheint. In dem Beispiel dauert es nur 3 Sekunden:

SQL:
SELECT 
 Kanal1, 
 timestamp
FROM 
 (SELECT @rownum:=0) AS vars, Februar
WHERE 
 timestamp BETWEEN 1298867639000 AND 1298877639000 AND 
    MOD((@rownum := @rownum+1), 7) = 0 
UNION SELECT
 Kanal1, 
 timestamp
FROM 
 (SELECT @rownum2:=0) AS vars, Maerz
WHERE 
 timestamp BETWEEN 1298867639000 AND 1298877639000 AND 
    MOD((@rownum2 := @rownum2+1), 7) = 0
  LIMIT 0, 2000

Auch wenn es nicht ganz so handlich ist wie in Antwort #5, kann ich damit erstmal leben und mir das in PHP mit Schleifen dynamisch zusammen bauen.
 
Zuletzt bearbeitet von einem Moderator:

Neue Beiträge

Zurück