[MySQL] Unbestimmte Anzahl Subquerys *erledigt*

joschilein

Multitalent
ID: 9301
L
5 Mai 2006
1.393
151
Um die Frage nicht unnötig kompliziert zu machen, habe ich mir kurz ein äquvalentes primitives Beispiel ausgedacht:

Es ist folgende Tabelle vorhanden:
Code:
Tabelle grundtest:
grund_id  lochtiefe
1            4 
1            3 
1            3 
1            2 
2            2
2            3
3            5
3            4
3            4
Mir dieser Abfrage
Code:
SELECT 
  `grund_id` as id
 , COUNT(*) as anzahl_löcher
 , (SELECT 
      COUNT(*)
      FROM `grundtest`
      WHERE `lochtiefe`=2
        AND `grund_id`=id
   ) as 2er
 , (SELECT 
      COUNT(*)
      FROM `grundtest`
      WHERE `lochtiefe`=3
        AND `grund_id`=id
   ) as 3er
 , (SELECT 
      COUNT(*)
      FROM `grundtest`
      WHERE `lochtiefe`=4
        AND `grund_id`=id
   ) as 4er
 , (SELECT 
      COUNT(*)
      FROM `grundtest`
      WHERE `lochtiefe`=5
        AND `grund_id`=id
   ) as 5er

FROM `grundtest`
GROUP BY `grund_id`
bekomme ich folgendes Ergebnis
Code:
id   	 anzahl_löcher 2er 3er 4er 5er
1 	4 	          1 	2   1   0
2 	2 	          1 	1   0   0
3 	3 	          0 	0   2   1
Das ist genau was ich haben will. Doch erstens gefällt mir diese Abfrage nicht so ganz und außerdem möchte ich mir über die Abfrage keine Gedanken mehr machen und auch ein vollständiges Ergebnis bekommen, wenn z.B. in der zweiten Zeile eine 6 als Lochtiefe stehen würde. Die Abfrage sollte also die verschiedenen Werte der Lochtiefe suchen (deren Anzahl halte ich programmmäßig in engen Grenzen, die genaue Anzahl ist aber unbekannt) und entsprechend und danach die Ergebnisspalten mit den entsprechenden Subquerrys füllen.
 
Zuletzt bearbeitet:
In einem einzigen Query würde ich es nicht hinkriegen, dazu kann ich zu wenig SQL, aber im Prinzip müsste es doch so gehen (aus Sicht der Middleware):

Code:
// pseudocode

query = "SELECT 
  `grund_id` as id
 , COUNT(*) as anzahl_löcher"

lochtiefen[] = sql(select distinct lochtiefe from grundtest)
foreach tiefe in lochtiefen {
  query += ", (SELECT COUNT(*) .... AS tiefe .... WHERE lochtiefe=tiefe)"
}
query += "FROM ..."

sql(query)
// here you go!

In der Art, wenns denn irgend möglich ist, oder?
 
Du kannst auch nach zwei Spalten GROUPen. Damit sollte sich das auch in einem Query zusammenfassen lassen können, wenn Du noch nach "lochtiefe" GROUPst. Dazu müsstest Du die Verarbeitung aber umstellen.

Guck mal, ob Du mit diesem Query was anfangen kannst:
Code:
SELECT grund_id, lochtiefe, COUNT( * )
FROM table
GROUP BY grund_id, lochtiefe
WITH ROLLUP
Dynamisch in einer Zeile wirst Du's wohl nicht vernünftig hinkriegen können.
 
einmal haste die möglichkeit wie tleilax sagt... jedoch entspricht die ausgabe des resultats nicht der geüwnschten, was man jedoch clientseitig kompensieren könnte.

alternativ kannste dir auch ne pivot abfrage basteln, ist jedoch auch nicht dynamisch. also du musst die werte wissen... jedoch ist dies bei weiten ressourcen schonender als jedes mal nen sub query.

PHP:
SELECT
	grund_id,
	COUNT(*) AS anzahl_löcher,
	SUM(IF(lochtiefe = 1, 1,0)) AS 1er,
	SUM(IF(lochtiefe = 2, 1,0)) AS 2er,
	SUM(IF(lochtiefe = 3, 1,0)) AS 3er,
	SUM(IF(lochtiefe = 4, 1,0)) AS 4er,
	SUM(IF(lochtiefe = 5, 1,0)) AS 5er,
	SUM(IF(lochtiefe = 6, 1,0)) AS 6er
FROM
	grundtest
GROUP BY
	grund_id
 
@bfabian:
Eine Möglichkeit über den Umweg PHP eine passende Abfrage zu basteln hätte ich auch hinbekommen, aber ich möchte zunehmend mehr die Kraft von SQL selbst nutzen.

@tleilax:
Hmm seltsam, ich hatte an anderer Stelle schonmal versucht mit zwei Spalten zu groupen, aber da habe ich immer Fehler bekommen.. War wohl noch was anderes in der Zeile falsch :(

@zerocc:
Im Prinzip ist das genau was ich gesucht habe. Ob da nun Subquerys drin sind oder nicht ist mir egal, so lange es das richtige Ergebnis liefert und schön anzuschauen ist. Die fehlende Dynamik ist hier nebensächlich, da man viel einfacher als bei meiner Lösung überblicken kann, welche möglichen Ergebnisse erfasst werden. Da werde ich eben für die ca. 15 möglichen Ergebnisse je eine Zeile einbauen, auch wenn die vorläufig nicht vorkommen werden. Nur jedes Mal 15 Subquerys abzugrasen, wovon 10 unnötig sind, wäre wirklich etwas leistungszehrend.
Also tolle Lösung :!: