MariaDB zwei Select miteinander verbinden

worst_case

Aktiver Benutzer
Beiträge
25
Hallo,

ich möchte zwei SELECT verbinden bzw. in einem Rutsch auslesen.
Das SELECT wird mit PHP zusammengebaut.
Es kann ein Name oder 5 Namen abgefragt werden, dementsprechend ist die Anfrage SELECT 2.

1. SELECT plcvarname FROM datapoints WHERE archivname = 'T1 Motordrehzahl' OR archivname = 'T1 Temperatur' ;
=> hieraus kommt eine Liste mit zwei Namen

2. SELECT `datetime`, `T1.Mdreh`, `T1.Temp` FROM archivvalue WHERE timeformat =1 AND `datetime` BETWEEN '2026-01-01' AND '2026-12-31';

Wie kann ich diese beiden "verbinden"?

Danke!!
 
Werbung:
Du suchst den Union-Befehl, hier ein Beispiel:

Code:
select 1
union
select 2;

wichtig, die beiden müssen dem selben Typen entsprechen!

EDIT:
Und die selbe Anzahl an Spalten haben


Ich denke, du suchst die Join-Befehle, verzeihung, genauer lesen.
 
Hallo,

nein ich möchte nicht das Ergebnis von 2 Tabellen, ich möchte dass das Ergebnis der ersten SELECT Anweisung in die nächste SELECT-Anweisung einfließt.
So in der Art ...

SELECT `datetime`, ???? IN (SELECT plcvarname FROM datapoints WHERE archivname = 'Turbine 1 Drehzahl' or archivname = 'Turbine 1 Leitrad') FROM archivvalue WHERE timeformat = 2 AND `datetime` BETWEEN '2026-01-01' AND '2026-12-31';

SELECT `datetime` + das Ergebnis der (SELECT ....)

Gruß
 
Zuletzt bearbeitet:
Der logische Zusammenhang ist leider nicht klar. Select 1 liefert eine Spalte plcvarname, sind diese Namen Voraussetzung für die WHERE-Bedingung in Select 2? Eventuell gibt es auch einen Zusammenhang über eine Spalte, die aktuell gar nicht in deinen Abfragen vorkommt. Oder sogar noch weitere Tabellen.
 
Der logische Zusammenhang ist leider nicht klar. Select 1 liefert eine Spalte plcvarname, sind diese Namen Voraussetzung für die WHERE-Bedingung in Select 2? Eventuell gibt es auch einen Zusammenhang über eine Spalte, die aktuell gar nicht in deinen Abfragen vorkommt. Oder sogar noch weitere Tabellen.
Hallo ukulele,

wie geschrieben soll das Ergebnis, ein Array von Namen, in die zweite SELECT eingefügt werden.
z.B. wäre das Ergebnis des ersten `T1.Mdreh`, `T1.Temp` ... dann sollte dies in das zweite select eingefügt werden ...

SELECT `datetime`, `T1.Mdreh`, `T1.Temp` FROM archivvalue WHERE timeformat =1 AND `datetime` BETWEEN '2026-01-01' AND '2026-12-31';

Vielen Dank für euer Bemühen.
 
Kannst du das einmal besser darstellen? Wie sehen die Tabellen aus? Wie soll das Ergebnis aussehen (aus welchen Selects sollen welche Daten kommen)?
 
Also das "einfachste" wäre ein CROSS JOIN.

Code:
SELECT datapoints.plcvarname, archivvalue.datetime, archivvalue.Mdreh, archivvalue.Temp
FROM
datapoints
CROSS JOIN archivvalue
WHERE ( datapoints.archivname = 'T1 Motordrehzahl' OR datapoints.archivname = 'T1 Temperatur' )
AND archivvalue.timeformat =1 AND archivvalue.datetime BETWEEN '2026-01-01' AND '2026-12-31'
Er setzt alle Werte aus der einen Tabelle mit allen Werten aus der anderen Tabelle in Relation. Sinnvoll ist das sehr selten und birgt ein gewisses Risiko, was die Menge an Ergebnisdatensätzen angeht.

Mich wundert auch noch ein wenig der T1 Alias, funktioniert Select 2 so wie er da steht überhaupt?
 
Hallo ukulele,

Code:
Code:
SELECT datapoints.plcvarname, archivvalue.datetime, archivvalue.Mdreh, archivvalue.Temp
FROM
datapoints
CROSS JOIN archivvalue
WHERE ( datapoints.archivname = 'T1 Motordrehzahl' OR datapoints.archivname = 'T1 Temperatur' )
AND archivvalue.timeformat =1 AND archivvalue.datetime BETWEEN '2026-01-01' AND '2026-12-31'

z.B. wäre das Ergebnis des ersten `T1.Mdreh`, `T1.Temp` ... dann sollte dies in das zweite select eingefügt werden ...

Somit kann ich nicht schreiben "archivvalue.Mdreh, archivvalue.Temp" da dies nur Platzhalter bzw. das Ergebnis aus dem ersten SELECT sind.

SQL:
SELECT datapoints.plcvarname, 'datetime', !!!Ergebnis aus SELECT muss hier rein!!!
        FROM
        datapoints
        CROSS JOIN archivvalue
        WHERE ( datapoints.archivname = 'T1 Motordrehzahl' OR datapoints.archivname = 'T1 Temperatur' )
        AND archivvalue.timeformat =1 AND archivvalue.datetime BETWEEN '2026-01-01' AND '2026-12-31'

Die einzigen "Festwerte in diesem Beispiel sind 'T1 Motordrehzahl' und 'T1 Temperatur' und ja die funktionieren.
Diese "Namen" werden dynamisch aus einem PHP Script erzeugt.

Nochmals, ich möchte zwei SELECT Anweisungen verbinden d.h. das Ergebnis des ersten SELECT soll als Parameter in die zweite SELECT Anweisung einfließen.
Ich möchte aus 2 Datenbankzugriffen nur einen Zugriff machen.

Vielen Dank, ich hoffe ich konnte die Anforderung besser erklären.
 
Zuletzt bearbeitet:
Jetzt wird die Sache klarer.

Grundsätzlich kannst du Inhalte aus Selects nicht zum Bestandteil des Querys machen. Es gibt nur eine Ausnahme mit dynamischem SQL. Dabei wird eine Variable deklariert, das SQL Statement dann in die Variable geschrieben (auch die abgefragten Spaltennamen) und dann wird mit EXEC(@var) das ganze ausgeführt. Das müsste auch in MySQL / MariaDB so gehen, allerdings fehlt mir da die Praxis. Du kannst das ja mal testen:

Code:
DECLARE @v NVARCHAR(1000)

SET @v = 'SELECT * FROM datapoints'

EXEC(@v);
Darauf kann man dann aufbauen. Das ganze kann auch in eine Funktion eingebaut werden.
 
Werbung:

Code:
DELIMITER $$

DROP PROCEDURE IF EXISTS build_archive_query$$

CREATE PROCEDURE build_archive_query()
BEGIN
    -- Variablen für den Cursor
    DECLARE v_done       INT DEFAULT FALSE;
    DECLARE v_plcvarname VARCHAR(255);
    DECLARE v_col1       VARCHAR(255) DEFAULT NULL;
    DECLARE v_col2       VARCHAR(255) DEFAULT NULL;
    DECLARE v_counter    INT DEFAULT 0;

    -- Dynamisch zusammengebauter SELECT-String
    DECLARE v_sql        TEXT;

    -- Cursor über die Spaltennamen aus datapoints
    DECLARE cur_cols CURSOR FOR
        SELECT plcvarname
        FROM datapoints
        WHERE archivname = 'T1 Motordrehzahl'
           OR archivname = 'T1 Temperatur';

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;

    -- ----------------------------------------------------------------
    -- Schritt 1: Spaltennamen per Cursor einlesen
    -- ----------------------------------------------------------------
    OPEN cur_cols;

    read_loop: LOOP
        FETCH cur_cols INTO v_plcvarname;

        IF v_done THEN
            LEAVE read_loop;
        END IF;

        SET v_counter = v_counter + 1;

        CASE v_counter
            WHEN 1 THEN SET v_col1 = v_plcvarname;   -- T1.Mdreh
            WHEN 2 THEN SET v_col2 = v_plcvarname;   -- T1.Temp
            ELSE BEGIN END;                           -- weitere Zeilen ignorieren
        END CASE;
    END LOOP;

    CLOSE cur_cols;

    -- ----------------------------------------------------------------
    -- Schritt 2: SELECT-String zusammenbauen
    -- ----------------------------------------------------------------
    SET v_sql = CONCAT(
        'SELECT `datetime`, `', v_col1, '`, `', v_col2, '` ',
        'FROM archivvalue ',
        'WHERE timeformat = 1 ',
        'AND `datetime` BETWEEN ''2026-01-01'' AND ''2026-12-31'';'
    );

    -- Optional: fertigen String zur Kontrolle ausgeben
    SELECT v_sql AS generated_sql;

    -- ----------------------------------------------------------------
    -- Schritt 3: Dynamisches SQL ausführen
    -- ----------------------------------------------------------------
    SET @dyn_sql = v_sql;
    PREPARE stmt FROM @dyn_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

END$$

DELIMITER ;

-- Prozedur aufrufen
CALL build_archive_query();

Die KI macht es natürlich recht ausführlich, aber das selbst zu schreiben ist auch etwas Frickelarbeit. Du brauchst einen CURSOR oder eine Schleife, weil dein erster Select eine unbekannte Anzahl an Spaltennamen liefern kann. Daher muss das eigentliche Query dann erst zusammen gebaut werden. Außerdem sind ein paar Sachen eventuell DBMS spezifisch, aber MySQL und MariaSB sind sich sehr ähnlich.

Übrigens ist das für ein produktives System nicht unbedingt die beste Vorgehensweise. Es kommt schnell zu Fehlern, weil die Datenintegrität nicht sichergestellt ist und es dürfte sehr unperformant laufen. Eventuell ist dein Datenbank-Design einfach schlecht, man sollte im Normalfall nicht auf so ein Verfahren angewiesen sein.
 
Zurück
Oben