Olaf Heinrich: MySQL Abfrage - Ausgabe nur wenn bestimmtes Ergebnis passt

Guten Morgen zusammen.

Folgende Situation:
Ich habe in einer Datenbank 2 Tabellen. Diese verfügen über jeweils mindestens 2 Identische Spalten. Einmal die Spalte "kd_id" in der eine Nummer des Kunden steht (Nicht die Kundennummer, sondern ein Schlüsselwert) und eine Palte mit dem Namen "kd_firma". In dieser befindet sich der Kudenstamm.

Mit:

$SQLAbfrage = "SELECT * FROM tst_arbeitsscheine AS t1, tst_kunden AS t2 WHERE t1.kd_ID = t2.kd_ID AND t1.schein_typ = '".$scheintyp."' AND MONTH(t1.schein_date)=".$timestamp." AND t2.kd_typ = '".$_POST["suchkreterium_art"]."' AND t2.kd_firma = '".$_POST["suchkreterium_stamm"]."'";  
$Ergebnis = mysql_query($SQLAbfrage, $iVerbNr) or die( "<H2>Will nicht suchen: </H2><P>". $SQLAbfrage . "</P>" . mysql_error());  
   $nAnzZeilen = mysql_num_rows($Ergebnis);  
   if ( $nAnzZeilen > 0 ) {  

vergleiche ich, ob der Kunde sowohl in Tabelle 1, wie auch in Tabelle 2 vorhanden ist. Ist dem so, wird der Inhalt aus Tabelle 1 zum entsprechenden Kunden ausgegeben.

Nun möchte ich folgenden Filter hinzufügen:
Nur wenn der Kunde in der Tabelle 1, also "tst_arbeitsscheine" 2 mal und mehr auftaucht, soll er für jeden Datensatz in Tabelle 2 der Anzahl entsprechend ausgegeben werden. Wie kann ich den Bezug auf Tabelle 1 herstellen?

Danke schon mal für Eure Denkstützen.

  1. Ich meine naturlich:  "..., soll er für jeden Datensatz in Tabelle 1". Sorry

    1. Hallo,

      Ich meine naturlich:  "..., soll er für jeden Datensatz in Tabelle 1". Sorry

      Machts jetzt auch nicht wirklich so viel klarer. ;)   Wenn du dein Datenschema erklären möchtest, bietet sich evt eine tabellarische Aufzeichnung des Ist-Zustandes an, hier mal so als Beispiel:

      Tabelle tst_arbeitsscheine
      -----------------------------------------
      kd_id | name | feldX
      ------------------------------------------
      1       | ABC  | skgkdgdgd

      Das gibt ein wenig mehr preis als so verschachtelte Haupt- und Nebensätze.

      Du willst zählen? ... Dann brauchst du die Aggregatsfunktion COUNT() und da du nicht einfach irgendwas zählen willst, sondern die Datensätze einer bestimmten Gruppe, benötigst du auch noch GROUP BY.

      Da du das als Bedingung/Beschränkung einsetzen möchtest, solltest du beides zusammen in die WHERE Klausel deiner Abfrage packen, dafür bietet sich eine korrelierende Unterabfrage (correlated subquery) an. Diese wird aber von MySQL erst ab 4.1 oder so unterstützt.

      Jetzt hast du schon mal 4 Stichworte mit denen du selbständig weitersuchen kannst.

      Ciao, Frank

  2. Hallo,

    Ich habe in einer Datenbank 2 Tabellen. Diese verfügen über jeweils mindestens 2 Identische Spalten. Einmal die Spalte "kd_id" in der eine Nummer des Kunden steht (Nicht die Kundennummer, sondern ein Schlüsselwert) und eine Palte mit dem Namen "kd_firma".

    Beispieldaten bitte.

    $SQLAbfrage = "SELECT * FROM tst_arbeitsscheine AS t1, tst_kunden AS t2 WHERE t1.kd_ID = t2.kd_ID AND t1.schein_typ = '".$scheintyp."' AND MONTH(t1.schein_date)=".$timestamp." AND t2.kd_typ = '".$_POST["suchkreterium_art"]."' AND t2.kd_firma = '".$_POST["suchkreterium_stamm"]."'";

    $Ergebnis = mysql_query($SQLAbfrage, $iVerbNr) or die( "<H2>Will nicht suchen: </H2><P>". $SQLAbfrage . "</P>" . mysql_error());
       $nAnzZeilen = mysql_num_rows($Ergebnis);
       if ( $nAnzZeilen > 0 ) {

      
    wenn man ein SQL-Problem hat, dann ist PHP-Code wenig hilfreich.  
      
    ~~~sql
      
    SELECT  
        *                      -- SELECT * ist böse[tm]  
    FROM  
        tst_arbeitsscheine t1, -- verbesserungswürdiger Aliasname  
        tst_kunden t2          -- ebenfalls optimierbarer Aliasname  
    WHERE  
            t1.kd_ID = t2.kd_ID  
        AND  
            t1.schein_typ = <irgendein scheintyp>  
        AND  
            MONTH(t1.schein_date) = <Zeitstempel, der keiner ist>  
        AND  
            t2.kd_typ = <Suchkriterium Art (und nicht Typ)>  
        AND  
            t2.kd_firma = <Suchkriterium Stamm>  
    
    

    schreiben wir es ein wenig um, verwenden explizite Joinsyntax und angemessenere Aliasnamen:

      
    SELECT  
        <spaltenliste>         -- Führe jede Spalte, die Du benötigst, einzeln auf  
    FROM                       -- aus  
        tst_arbeitsscheine a   -- Tabelle arbeitsscheine, die  
    INNER JOIN                 -- mit  
        tst_kunden k           -- Tabelle kunden  
    ON                         -- über  
            a.kd_ID = k.kd_ID  -- gleiche ID-Werte verknüpft ist  
    WHERE                      -- wobei uns nur eine  
            a.schein_typ = <scheintyp>       -- bestimmte Scheinart, die  
        AND  
            MONTH(a.schein_date) = <monat>  -- in einem bestimmten Monat  
        AND  
            k.kd_typ = <Suchkriterium Kundentyp>  -- von bestimmten Kundentypen  
        AND  
            k.kd_firma = <Suchkriterium Stamm>    -- einer bestimmten Firma  
                                                  -- interessieren  
    
    

    Ich kann nicht erkennen, dass die Spalten kd_firma in beiden Tabellen vorhanden ist und die Werte übereinstimmen müssten.

    Nun möchte ich folgenden Filter hinzufügen:
    Nur wenn der Kunde in der Tabelle 1, also "tst_arbeitsscheine" 2 mal und mehr auftaucht, soll er für jeden Datensatz in Tabelle 2 der Anzahl entsprechend ausgegeben werden. Wie kann ich den Bezug auf Tabelle 1 herstellen?

    allgemein zweimal in der Tabelle Arbeitsscheine oder zweimal mit dieser bestimmten Scheinart und im gewünschten Monat?

    Nutze ein Subselect. (MySQL 4.1 und neuer, sollte die MySQL-Version älter sein, und der Hoster nicht bereit, zu aktualisieren, wäre dies ein Umzugsgrund). Im Subselect verwende COUNT und die HAVING-Klausel.

    Zu Deinem PHP-Code:

    a) die() ist keine Fehlerbehandlung, siehe Zitat 1282.
    b) Behandle Daten die von außen kommen, kontextgemäß. Da Du noch die veralteten
       mysql_*-Funktionen verwendest, wäre dies mysql_real_escape_string().
       Falls Du Dich auf die Magic Quotes verläßt - und diese aktiviert sind,
       solltest Du deren Auswirkungen beim Skriptbeginn rückgängig machen, so wie
       es auf der verlinkten Handbuchseite beschrieben ist.

    Freundliche Grüße

    Vinzenz