[MySQL] - grösster UND zweitgrösster Wert der gleichen Spalte abfragen

TehQuila

Grünschnabel
Hi Leute

Ich habe ein Problem mit einer Abfrage:
Ich möchte aus einer Tabelle den grössten und den zweitgrössten Wert gleichzeitig mit einem SELECT aus der selben Spalte abfragen.

Meine Tabellen sehen folgendermassen aus:
In der Tabelle "swauditlogs" gibt es die Spalte "dateline". Von dieser Spalte "dateline" möchte ich den grössten und zweitgrössten Wert für die jeweilige "ticketmaskid" aus der Tabelle "swtickets" erhalten.

Dies ist meine Abfrage wie ich sie bis jetzt zusammen habe:
Code:
SELECT MAX(`swauditlogs`.dateline) AS last_response, `swtickets`.ticketmaskid FROM `swauditlogs`
JOIN `swtickets` ON `swauditlogs`.ticketid = `swtickets`.ticketid
WHERE `swauditlogs`.ticketid = `swtickets`.ticketid
AND `swtickets`.ticketstatusid = 1
AND `swtickets`.departmentid = 1
AND `swauditlogs`.actiontype = 12
GROUP BY `swtickets`.ticketmaskid

Mit MAX() bekomme ich ja den grössten wert der Spalte "dateline" in der Tabelle "swauditlogs" zurück.

Jetzt möchte ich aber in der gleichen Abfrage auch noch den zweitgrössten Wert zurückbekommen.

Ich habe noch eine Abfrage mit der ich den zweitgrössten Wert erhalte:
Code:
SELECT dateline AS second_last_response FROM `swauditlogs`
WHERE ticketid = 4744
AND actiontype = 12
ORDER BY dateline DESC
LIMIT 1,1

Wie kann ich also diese zwei Abfragen zusammenführen zu einer? Ist dies überhaupt möglich?
Und wenn ja, wie?

Als Resultat hätte ich gerne etwas, dass so ähnlich aussieht:
+---------------+-----------------+--------------------------+
| ticketmaskid | last_response | second_last_response |
+---------------+-----------------+--------------------------+
| jeweilige ID | grösster Wert | zweitgröster Wert |
+---------------+-----------------+--------------------------+

Vielen Dank für eure Hilfe schon im voraus :)
Gruss TehQuila
 
Hach, ich mag komplexe SQLs *g*

Etwa so könnt es gehen
SQL:
SELECT
	ticketmaskid,
	MAX(IF(itemNum = 0, dateline, "")) AS last_response,
	MAX(IF(itemNum = 1, dateline, "")) AS second_last_response
FROM
	(
		SELECT
			ticketid,
			dateline,
			-- Prüfen ob die Ticketmaske noch übereinstimmt - Wenn ja, itemNum um eins erhöhen, ansonsten auf 0 setzen
			@itemNum := IF(ticketmaskid = @lastMaskID, @itemNum+1, 0) AS itemNum,
			-- ticketmaskid für die nächste Zeile in die Variabel speichern
			@lastMaskID := ticketmaskid AS ticketmaskid
		FROM
			-- Variablen initialisieren
			(SELECT @lastMaskID := '', @itemNum := 0) AS vars,
			-- Sortierte Quelle
			(
				SELECT
					l.ticketid,
					l.dateline,
					t.ticketmaskid
				FROM
					swauditlogs AS l
					INNER JOIN swtickets AS t
						ON l.ticketid = t.ticketid
				ORDER BY
					t.ticketmaskid,
					l.dateline DESC
			) AS dat
	) AS sortetDat
WHERE
	itemNum < 2	
GROUP BY
	ticketmaskid;
 
Zuletzt bearbeitet von einem Moderator:
Wow so eine Abfrage hab ich noch nie gesehen :)
Vielen Dank für die rasche Antwort!
Hab sie gleich mal ausprobiert und sie hat auch beinahe funktioniert.

Die Spalte mit den "ticketmaskid's" stimmt super. "last_response" und "second_last_response" sind jedoch nicht die Daten welche in der Tabelle "swauditlogs" stehen, dass sind nämlich Timestamps (hätte ich vielleicht von Anfang an erwähnen sollen).

Das Ergebnis sieht folgendermassen aus:

ticketmaskid
  1. AAG-349271
  2. AAO-480120
  3. AAR-636170

last_response
  1. 31323939303534313032
  2. 31323835353637363031
  3. 31323636393239303830

second_last_response
  1. 31323939303534313032
  2. 31323636393239303830
  3. 31323835353637363031

Auch habe ich bei der Abfrage nicht genau gewusst wo ich meine "Einschränkungen" für die Abfrage hinpacken soll. Ich hab es an dieser Stelle probiert, da hab ich jedoch ein Syntax-Error bekommen:

Code:
(SELECT @lastMaskID := '', @itemNum := 0) AS vars, (
	SELECT
		l.ticketid,
		l.dateline,
		t.ticketmaskid
	FROM
		swauditlogs AS l
		INNER JOIN `swtickets` AS t
		ON l.ticketid = t.ticketid
	ORDER BY
		t.ticketmaskid,
		l.dateline DESC

----Meine Where-Klausel----
	WHERE
		t.ticketstatusid = 1
		t.departmentid = 1
		l.actiontype = 12
----Ende meiner Where-Klausel----

) AS dat

Vielen Dank für deine Hilfe
Gruss TehQuila
 
Die Spalte mit den "ticketmaskid's" stimmt super. "last_response" und "second_last_response" sind jedoch nicht die Daten welche in der Tabelle "swauditlogs" stehen, dass sind nämlich Timestamps (hätte ich vielleicht von Anfang an erwähnen sollen).
Was erscheint und was sollte erscheinen? Am Besten als Beispiel

Das WHERE
Am besten in den innersten Select. Das hast du eigentlich richtig, jedoch muss das WHERE vor den ORDER BY sein (Normale SELECT-Syntax)
SQL:
(
    SELECT
        l.ticketid,
        l.dateline,
        t.ticketmaskid
    FROM
        swauditlogs AS l
        INNER JOIN `swtickets` AS t
        ON l.ticketid = t.ticketid
----Meine Where-Klausel----
    WHERE
        t.ticketstatusid = 1
        t.departmentid = 1
        l.actiontype = 12
----Ende meiner Where-Klausel----
    ORDER BY
        t.ticketmaskid,
        l.dateline DESC
) AS dat
 
Zuletzt bearbeitet von einem Moderator:
Was erscheint und was sollte erscheinen? Am Besten als Beispiel

Entschuldige habe es nicht ausführlich gesagt.
Das sind die Daten welche im Moment zurückkommen:

ticketmaskid
  1. AAG-349271
  2. AAO-480120
  3. AAR-636170

last_response
  1. 31323939303534313032
  2. 31323835353637363031
  3. 31323636393239303830

second_last_response
  1. 31323939303534313032
  2. 31323636393239303830
  3. 31323835353637363031

Und diese Daten stehen effektiv in der Datenbank:

ticketmaskid
  1. AAG-349271
  2. AAO-480120
  3. AAR-636170

last_response
  1. 1266922501
  2. 1285567601
  3. 1299054102

second_last_response
  1. 1266918213
  2. 1285564359
  3. 1299053904

Habe meine Where-Klausel jetzt ans richtige Ort gepackt. (und auch mit Kommas versehen)
Leider bekomme ich immer noch einen Syntax Error bei diesen Zeilen:
SQL:
SELECT
    l.ticketid,
    l.dateline,
    t.ticketmaskid
FROM
    swauditlogs AS l
    INNER JOIN swtickets AS t
        ON l.ticketid = t.ticketid
WHERE
    t.ticketstatusid = 1,
    t.departmentid = 1,
    l.actiontype = 12
ORDER BY
    t.ticketmaskid,
    l.dateline DESC

Vielen Dank für deine Unterstützung :)
 
Zuletzt bearbeitet von einem Moderator:
Syntax:
Hab nicht gut hingeschaut und darum den 2ten Fehler nicht gleich gesehen.
WHERE-Teile verbindet man nicht mit Kommas, sondern mit den Worten AND oder OR
SQL:
WHERE
    t.ticketstatusid = 1
    AND t.departmentid = 1
    AND l.actiontype = 12

Sind deine Daten geheim? Ansonsten kannst du mal die CREATE-Table-Scripte und die dazugehörigen INSERT-Scripte exportieren und hier reinstellen? Dann kann ich mit denselben Daten testen - macht es einfacher
 
Zuletzt bearbeitet von einem Moderator:
WHERE-Teile verbindet man nicht mit Kommas, sondern mit den Worten AND oder OR
Stimmt. Im Nachhinein ist mir das jetzt auch aufgefallen. Diese ungewohnte Darstellungsweise der Abfrage hat mich gänzlich von meiner gewohnten SQL-Syntax abgebracht. :)

Habe im Anhang die Skripts reingepackt. Habe alle persönlichen Daten entfernt und nur einige Beispieldaten von den benötigten Spalten aus den beiden Tabellen reingepackt eine Datenbank müsstest du noch erstellen wenn das in Ordnung geht. Hoffe das funktioniert so für dich.

Danke für deine Hilfe :)
Gruss TehQuila
 

Anhänge

  • swauditlogs.txt
    1,4 KB · Aufrufe: 15
  • swtickets.txt
    1,4 KB · Aufrufe: 14
Also, diene Testdaten passen nicht mir deinem Beispielen von oben überein.
Dies ist mein Resultat daraus:
Code:
ticketmaskid | last_response | second_last_response
---------------------------------------------------
DMH-577763   | 1178487063    | 1178467063
DYF-523660   | 1280968206    | 1280068206
OGG-307356   | 1180178206    | 1180068206
SCG-166410   | 1380069867    | 1380068206

Und welches hättest d denn gerne?
 
Code:
ticketmaskid | last_response | second_last_response
---------------------------------------------------
DMH-577763   | 1178487063    | 1178467063
DYF-523660   | 1280968206    | 1280068206
OGG-307356   | 1180178206    | 1180068206
SCG-166410   | 1380069867    | 1380068206

Genau das sollte meiner Meinung nach auch rauskommen tut es jedoch nicht...
Meine Testdaten sind Timestamps genau wie in der Datenbank auch (einfach andere als in meinen Beispielen zuvor)

Ich habe den Code: (nur um sicher zu gehen dass ich keine Schreibfehler im Nachhinein gemacht habe)
SQL:
SELECT
    ticketmaskid,
    MAX(IF(itemNum = 0, dateline, "")) AS last_response,
    MAX(IF(itemNum = 1, dateline, "")) AS second_last_response
FROM
    (
        SELECT
            ticketid,
            dateline,
            @itemNum := IF(ticketmaskid = @lastMaskID, @itemNum+1, 0) AS itemNum,
            @lastMaskID := ticketmaskid AS ticketmaskid
        FROM
            (SELECT @lastMaskID := '', @itemNum := 0) AS vars,
            (
                SELECT
                    l.ticketid,
                    l.dateline,
                    t.ticketmaskid
                FROM
                    swauditlogs AS l
                    INNER JOIN swtickets AS t
                        ON l.ticketid = t.ticketid
                WHERE
                    t.ticketstatusid = 1
                    AND t.departmentid = 1
                    AND l.actiontype = 12
                ORDER BY
                    t.ticketmaskid,
                    l.dateline DESC
            ) AS dat
    ) AS sortetDat
WHERE
    itemNum < 2 
GROUP BY
    ticketmaskid;

Bei Phpmyadmin laufen lassen und da kommt jetzt (mit den funktionierenden Einschränkungen) das hier dabei raus:
Code:
ticketmaskid| last_response         | second_last_response
---------------------------------------------------------
BIJ-774601	| 31333137383932343337	| 31333137383838363132
CKB-916753	| 31333138393430363733	| 31333138393430363733
FNY-416858	| 31333139353530393031	| 31333139353439353538
JDU-169012	| 31333137393930333031	| 31333137393638363331
KZS-989678	| 31333138333232313133	|  
MBF-935585	| 31333139353430373530	| 31333139343337333531
MGK-279728	| 31333139303331393633	|  
MUG-995038	| 31333138393630323031	| 31333138393538373031
RBA-571455	| 31333137393038373837	|  
TIM-174440	| 31333138393536343237	|  
WEW-345711	| 31333137383737393039	|  
WYH-740816	| 31333135393033353837	| 31333131363631333230
YBT-835218	| 31333139343439383031	| 31333139343437373334

Sehe leider nicht was ich falsch mache... wie hast du denn diese Query ausgeführt?

Danke für deine Unterstützung
Gruss TehQuila
 
Zuletzt bearbeitet von einem Moderator:
Zurück