SELECT COUNT(*) in einer do-Schleife richtig ordnen

Ich kann mir gut vorstellen, dass es dafür eine Funktion geben könnte.

Ich versuch mal mein Vorhaben etwas genauer zu beschreiben.

Ich habe zwei Tabellen, eine mit Temindaten und eine mit Adressdaten eines Vereins.
in einer Verknüpfungstabelle hab ich zu jeder ID der Termine jede ID der Adressen sowie eine Spalte für den Status (1= Entschuldigt, 2= Anwesend, 3= unentschuldigt). So kann ich eine Anwesenheitskontrolle führen.

nun möchte ich anzeigen wer, wie oft anwesend war.

Jetzt frag ich, in der do-Schleife, mit SELECT COUNT(*) für jedes Mitglied die Anzahl der Datensätze ab wo 2 Steht.

Da ich zudem gerne eine kleine Rangliste erhalten möchte, hätte ich gerne jene Mirglieder mit der meisten präsenzzeit zu oberst und jene mit wenigsten zu unterst.

PHP:
<?php do { ?>              
              <tr> 
                <td width="279" height="19">
<?php echo $row_mitglieder['ad_nachname']; ?> 
<?php echo $row_mitglieder['ad_vorname']; ?>
</td> 
    <td width="91" height="19"><div align="center">
<?php 
                 
$colname_absenzen_anw_anw = "-1"; 
if (isset($row_mitglieder['ad_ID'])) { 
  $colname_absenzen_anw_anw = $row_mitglieder['ad_ID']; 
} 
mysql_select_db($database_PopularisBischofszell, $PopularisBischofszell); 
$query_absenzen_anw_anw = sprint
("SELECT COUNT(*) 
FROM `pobi_adressen` as `t1` left JOIN `pobi_adrterm` as `t2` ON `t1`.`ad_ID` = `t2`.`adte_IDadr` 
WHERE (adte_status = 2) 
AND (adte_IDadr = %s) 
AND ((ad_austritt = 0 and ad_aufgenommen <> 0) 
OR (ad_probejahr <> 0 and ad_aufgenommen = 0 and ad_austritt = 0)) 
ORDER BY adte_status ASC", 
GetSQLValueString($colname_absenzen_anw_anw, "int")); 
$absenzen_anw_anw = mysql_query($query_absenzen_anw_anw, $PopularisBischofszell) or die(mysql_error()); 
$row_absenzen_anw_anw = mysql_fetch_assoc($absenzen_anw_anw); 
$totalRows_absenzen_anw_anw = mysql_num_rows($absenzen_anw_anw); 

<?php
echo $row_absenzen_anw_anw['COUNT(*)'];
?>  
                </div></td> 

} while ($row_mitglieder = mysql_fetch_assoc($mitglieder))
?>


Wenn die ID der Adressen mit dem Fremdschlüssel in der Verknüpfunktstabelle übereinstimmen, werden die Datensätze gezählt wo 2 in der Spalte adte_status steht.

das ergibt mir dann eine Auflisteung aller Namen und deren anzahl Anwesenheit.
 
Das machst du alles mit einer Abfrage und zwar in der die dir dieses Ergebnis liefert:
PHP:
 while ($row_mitglieder = mysql_fetch_assoc($mitglieder))

In der Abfrage Joins du einfach die Tabelle, gruppierst sie nach den Personen und zählst deren Fehltage und danach kannst du das Ergebnis auf- oder absteigend sortieren. Das machst du alles über SQl.
 
So wie ich das verstanden habe, lässt er eine Schleife laufen die entsprechend jeden Durchgang einen Count ausgibt, welchen er speichern (Array) möchte.
Den Array möchte er dann sortiert ausgeben.
Genau das möchte ich.

PS: Ich kenn mich beim Sortieren halt nur in der Theorie aus, nicht in der Praxis. Gibt ja genug Algorithmen die zu einer Lösung führen....
Ich kenn mich gar nicht aus damit.

@Yaslaw: was meinst du mit:
¨
Wennn ich wüsste wie der Array aussehen sollte,
 
@Yaslaw: was meinst du mit [...]

Naja, damit du nachher auch die Personen dem jeweiligen Wert zuweisen kannst, brauchst du entweder einen zweidimensionalen Array, oder du machst es z.B. über im-/explode...

Zweidimensionaler Array:
PHP:
$array[0] = array(name => "Hans", count => "17");
$array[1] = array(name => "Günther", count => "15");
$array[2] = array(name => "Markus", count => "13");

Ex-/Implodemethode:
PHP:
$array[0] = "Hans---17";
$array[1] = "Günther---15";
$array[2] = "Markus---13";

Persönlich würde ich die zweite Methode nehmen, ist zwar unschöner aber schlussendlich meiner Meinung nach simpler.
Wie man einen Array ordnet, kann ich dir beim besten Willen nicht sagen. Problematisch bei Version2 ist halt, dass da Namen drin sind. Die kann man wohl kaum ordnen...
 
Ok ich hab jetzt mal etwas betreffend Arrays gelesen.
Schreib ich dann mit einer Schleife in das Array?

Ich hab da mal etwas probiert, allerdings ohne grossen Erfolg.

PHP:
do { 


$colname_absenzen_anw = "-1";
if (isset($row_mitglieder['ad_ID'])) {
  $colname_absenzen_anw = $row_mitglieder['ad_ID'];
}
mysql_select_db($database_PopularisBischofszell, $PopularisBischofszell);
$query_absenzen_anw = sprintf("SELECT COUNT(*) FROM `pobi_adressen` as `t1` left JOIN `pobi_adrterm` as `t2` ON `t1`.`ad_ID` = `t2`.`adte_IDadr` WHERE (adte_status = 2) AND (adte_IDadr = %s) AND  ((ad_austritt = 0 and ad_aufgenommen <> 0) or (ad_probejahr <> 0 and ad_aufgenommen = 0 and ad_austritt = 0)) ORDER BY adte_status ASC", GetSQLValueString($colname_absenzen_anw, "int"));
$absenzen_anw = mysql_query($query_absenzen_anw, $PopularisBischofszell) or die(mysql_error());
$row_absenzen_anw = mysql_fetch_assoc($absenzen_anw);
$totalRows_absenzen_anw = mysql_num_rows($absenzen_anw);

$colname_absenzen_unent = "-1";
if (isset($row_mitglieder['ad_ID'])) {
  $colname_absenzen_unent = $row_mitglieder['ad_ID'];
}
mysql_select_db($database_PopularisBischofszell, $PopularisBischofszell);
$query_absenzen_unent = sprintf("SELECT COUNT(*) FROM `pobi_adressen` as `t1` left JOIN `pobi_adrterm` as `t2` ON `t1`.`ad_ID` = `t2`.`adte_IDadr` WHERE (adte_status = 3) AND (adte_IDadr = %s) AND  ((ad_austritt = 0 and ad_aufgenommen <> 0) or (ad_probejahr <> 0 and ad_aufgenommen = 0 and ad_austritt = 0))", GetSQLValueString($colname_absenzen_unent, "int"));
$absenzen_unent = mysql_query($query_absenzen_unent, $PopularisBischofszell) or die(mysql_error());
$row_absenzen_unent = mysql_fetch_assoc($absenzen_unent);
$totalRows_absenzen_unent = mysql_num_rows($absenzen_unent);

$array[0] = array(nachname => $row_mitglieder['ad_nachname'], vorname => $row_mitglieder['ad_vorname'], count => $row_absenzen_anw['COUNT(*)'], unent => $row_absenzen_unent['COUNT(*)']);

} while ($row_mitglieder = mysql_fetch_assoc($mitglieder))?>
 
Ist zwar keine Antwort weil:
item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen

Willst du dein Code nicht formatieren?
Auch SQLs sind Formatiert lesbar. In deiner Form leider nicht.

PHP:
//Vergleich mal deins
$query_absenzen_unent = sprintf("SELECT COUNT(*) FROM `pobi_adressen` as `t1` left JOIN `pobi_adrterm` as `t2` ON `t1`.`ad_ID` = `t2`.`adte_IDadr` WHERE (adte_status = 3) AND (adte_IDadr = %s) AND  ((ad_austritt = 0 and ad_aufgenommen <> 0) or (ad_probejahr <> 0 and ad_aufgenommen = 0 and ad_austritt = 0))", GetSQLValueString($colname_absenzen_unent, "int")); 

//versus das
$query_absenzen_anw  = <<<SQL
SELECT 
    COUNT(*) 
FROM 
    pobi_adressen as t1 
    LEFT JOIN pobi_adrterm AS t2 
        ON t1.ad_ID = t2.adte_IDadr
WHERE 
    t2.adte_status = 2 
    AND t2.adte_IDadr = %s 
    AND (
            (t1.ad_austritt = 0 
            AND t1.ad_aufgenommen <> 0) 
        OR 
            (t1.ad_probejahr <> 0 
            AND t1.ad_aufgenommen = 0 
            AND t1.ad_austritt = 0)
        ) 
ORDER BY
    adte_status ASC
SQL;
$query_absenzen_anw = sprintf($query_absenzen_anw, GetSQLValueString($colname_absenzen_anw, "int"));

Zudem, alles was in der do{} drin ist, kann man auch einrücken um zu sehen von wo bis wo die Schleife geht
 
Hallo Yaslaw

Ich kann dich gut verstehen wenn du nicht erfreut bist über unformatierte Codes.
Mann verzeihe mir,
Ich werde mich bemühen, künftig meine Codes anschaulicher darzustellen.

Vielleicht hilfst du mir trotzdem weiter bei meinem Problem.

Wie schreib ich aus einer Abfrage mehrere Ergebnisse in ein Array und das in einer Schleife?

Freundliche Grüsse
Phips_CH
 
Sorry, ich versteh leider immer noch nicht was du genau was du haben willst, was bei deinen Arrays nicht funktioniert (Fehlermeldungen? Falsche Resultate? Wenn ja, welche?), was ein Array

item: $totalRows_absenzen_anw = mysql_num_rows($absenzen_anw);
$totalRows_absenzen_anw ist logischerweise immer 1, da ein SELECT COUNT(*) FROM immer genau eine Zeile ausgibt.
Also kannst du dir diese Verwirrung sparen

item: Wenn du in den Count-SQL ein Feld-Alias setzt, kannst du nachher eleganter drauf zugreifen
SQL:
SELECT
    COUNT(*) AS cnt_adr
FROM
    pobi_adressen
...
Dann kannst du so drauf zugreiffen
PHP:
echo $row_absenzen_anw['cnt_adr'];

item: Die SQLS lassen sich wahrscheinlich verknüpfen. Hab aber grad keine Lust alles zu formatieren, zu analysieren, zu verstehen und umzubauen.

item: in der folgenden Zeile setzt du dein Array zusammen.
$array[0] = array(nachname => $row_mitglieder['ad_nachname'], vorname => $row_mitglieder['ad_vorname'], count => $row_absenzen_anw['COUNT(*)'], unent => $row_absenzen_unent['COUNT(*)']);
Du schreibst aber immer alles in den Index 0 von $array. Somit überschreibst du bei jedem Durchgang durch die Schleife den Eintrag auf Index 0. Wenn du ein 2-Dimensionalen Array haben willst, dann lass die Nummer weg damit jedes mal ein euer Eintrag in den Array geschrieben wird
PHP:
//Array initialzieren
$array = array();
do{
    ...
    //Hier keinen Index angeben
    $array[] = array(
            nachname => $row_mitglieder['ad_nachname'], 
            vorname => $row_mitglieder['ad_vorname'], 
            count => $row_absenzen_anw['COUNT(*)'], 
            unent => $row_absenzen_unent['COUNT(*)']
	);
    ....
} while ($row_mitglieder = mysql_fetch_assoc($mitglieder))?>
 
Zuletzt bearbeitet von einem Moderator:
So wenn ich das richtig sehe gibt es 2 entscheidende Tabellen mit folgenden Feldern (oder so ungefähr):

pobi_adrterm
adte_IDmitglied
adte_IDadr
adte_status

pobi_mitglieder
ad_id
ad_nachname
ad_vorname

Mit folgender Abfrage kann man die gewünschte Ergebnismenge erhalten, ohne diese Zwischenabfragen in der do-while Schleife und das mit den Arrays ist auch völlig überflüssig.

SQL:
SELECT `m`.`ad_vorname` AS `Vorname`,`m`.`ad_nachname` AS `Nachname`,
  SUM(if(`t`.`adte_status`=1,1,0)) AS `Entschuldigt`,
  SUM(if(`t`.`adte_status`=2,1,0)) AS `Anwesend`,
  SUM(if(`t`.`adte_status`=3,1,0)) AS `unentschuldigt`
FROM `pobi_mitglieder` AS `m`
LEFT JOIN `pobi_adrterm` AS `t` ON `m`.`ad_id`=`t`.`adte_IDmitglied`
GROUP BY `adte_IDmitglied`
ORDER BY `Anwesend` DESC

Die Ausgabe sieht dann ungefähr so aus:
Code:
+---------+----------+--------------+----------+----------------+
| Vorname | Nachname | Entschuldigt | Anwesend | unentschuldigt |
+---------+----------+--------------+----------+----------------+
| Bar1    | Foo1     |            0 |        2 |              1 |
| Bar3    | Foo3     |            0 |        1 |              0 |
| Bar2    | Foo2     |            0 |        0 |              0 |
+---------+----------+--------------+----------+----------------+

Mit den richtigen Tabellen könnte man das Statement richtig formulieren ...
 
Zuletzt bearbeitet von einem Moderator:
Ich habe zwei Tabellen.

zum einen die Tabelle
pobi_adressenmit den Feldern
ad_ID
ad_Nachname
ad_vorname
ad_austritt
ad_aufgenommen
ad_probejahr

zum andern die Tabelle
pobi_adrterm die aus der Feldern
adte_ID
adte_IDadr
adte_IDter
adte_status

Die Tabelle pobi_adrterm ist eine Verknüpfungstabelle. in adte_IDadr steht der Wert von pobi_adressen.ad_ID drin. In adte_IDter steh die ID einer weiteren Tabelle, wo ich alle Termine und Anlässe speichere.

mit:
PHP:
WHERE (adte_status = 2) 
	AND (adte_IDadr = %s) 
	AND ((ad_austritt = 0 
	AND ad_aufgenommen <> 0) 
	OR  (ad_probejahr <> 0 
	AND ad_aufgenommen = 0 
	AND ad_austritt = 0))

frag ich ab, ob ein Mitglied noch im Ferien ist. Denn ich möchte nur diese Anzeigen.

Nun möchte ich für jedes Mitglied die Anzahl der Datensätze, aus der Tabelle pobi_adrterm wo bei adte_status eine 2 steht.

Die Ausgabe würde (sollte) dann so aussehen. hinter jedem Vor-/Nachname steht dann wie oft er Anwesend war (bei adte_status eine 2 steht) und zur Info wie oft er Unentschuldigt fern blieb (bei adte_status eine 3 steht).
In der Tabelle sollte dann das Mitglied, welches am meisten Anwesend war, zuoberst stehen.

Wie kann ich die Ergebnisse dann Ausgeben?
 
Zurück