Stefan: mysql5 - Vorgehensweise gesucht

Hallo,

ich habe ein Mahnwesen installiert, das über 2 bzw. 3 Tabellen die Mahnungen verwaltet.

---------------------------------------------------------------
 Mahnstatus Mahnbetreff Mahntext
 ER             ...             ...
 1M
 2M
 3M

ID RGID Mahnstatus Mahndatum Faelligkeit
1 1115    ER              2013-01-30      7
2        997    ER              2013-01-31      7
3 ...

RGID      RGdatum Faelligkeit     bezahlt(0 oder 1)
1         2012-12-22    14              1
2 ...

---------------------------------------------------------------

Die erste Tabelle beherbergt Die verschiedenen Mahnstufen, also Erinnerung, 1. Mahnung, 2. Mahnung. Eben soviele, wie der User anlegen will.

In der 2. Tabelle werden zu jeder Rechnung die Mahnstufen (falls versendet) gespeichert.

Nun möchte ich in meiner Rechnungsübersicht mit Symbolen darstellen, welche Rechnung

1. eine Mahnstufe enthält.
2. Für eine (weitere) Mahnstufe fällig ist.

Meine Idee ist, für nicht fällige und nicht angemahnte Rechnungen nichts anzuzeigen.

Für Rechnungen je angemahnter Stufe ein PNG, das einen schwarzen Punkt enthält.

Und falls eine neue Mahnstufe erreicht ist, hinten dran ein PNG mit rotem Punkt.

Also könnte die Rechnungenübersicht so aussehen:

  • = nichts

= schwarzer Punkt

* = roter Punkt

RG1 -
RG2 #*
RG3 -
RG4 *
RG5 ##*
RG6 ###
RG7 ###*

Auf welche Art frage ich bei vorhandener Rechnungsnummer am sinnvollsten die DB ab, um effektiv mein Ziel zu erreichen?

Mir geht es nicht um die Query selber, ich frage nach der Vorgehensweise.

Danke für Hilfe, Stefan

  1. Hast du ein WHERE mit dem die die Anzahl der in Frage kommenden Rechnungen schon sinnvoll begrenzt wird?
    Dann ist das hinzujoinen der Mahnungen wahrscheinlich schon nicht mehr so kritisch.

    Sind die Mahnungen immer in einer bestimmten Reihenfolge? Dann würde ich ein GROUP BY Rechnung machen und mit einem MAX(Mahnungsrelevanz) die letzte Mahnung zur Rechnung ausgeben. Daran weißt du dann welche Mahnungen die Rechnung schon erhalten hat und kannst das anzeigen.

    Was ich nicht verstehe

    bei vorhandener Rechnungsnummer

    Du willst hoffentlich nicht für jede Rechnung separat alle Mahnungen suchen?

    1. Hi encoder,

      danke für Deine Antwort. Das waren genau die Denkanstöße, die ich brauchte.

      Hast du ein WHERE mit dem die die Anzahl der in Frage kommenden Rechnungen schon sinnvoll begrenzt wird?

      Ja, das natürlich ohnehin.

      Dann ist das hinzujoinen der Mahnungen wahrscheinlich schon nicht mehr so kritisch.

      Korrekt.

      Sind die Mahnungen immer in einer bestimmten Reihenfolge? Dann würde ich ein GROUP BY Rechnung machen und mit einem MAX(Mahnungsrelevanz) die letzte Mahnung zur Rechnung ausgeben. Daran weißt du dann welche Mahnungen die Rechnung schon erhalten hat und kannst das anzeigen.

      Das war der entscheidende Hinweis.

      Was ich nicht verstehe

      bei vorhandener Rechnungsnummer
      Du willst hoffentlich nicht für jede Rechnung separat alle Mahnungen suchen?

      Wäre jetzt auch nicht so dramatisch gewesen (s.o. LIMIT), aber natürlich integriere ich den JOIN (bzw. LEFT JOIN) in die bereits vorhandene "Hauptquery).

      Was  noch ein bißchen unklar bei mir ist, ist beim vorhandenen JOIN

        
      ...  
      ADDDATE(r.Rechnung_datum , INTERVAL r.Faelligkeitstage DAY),  
      m.Mahnstatus,  
      ADDDATE(m.Mahn_datum, INTERVAL m.Faelligkeitstage DAY)  
      ...  
      
      

      lediglich den höchsten Mahnstatus UND das hierzu gehörende Mahndatum+Fälligkeit zu erhalten.

      Über das Einbinden von MAX(m.Mahnstatus) in die WHERE-Klausel erhalte ich einen Fehler #1111 - Invalid use of group function.

      Gruß, Stefan

      1. Was  noch ein bißchen unklar bei mir ist, ist beim vorhandenen JOIN

        ...
        ADDDATE(r.Rechnung_datum , INTERVAL r.Faelligkeitstage DAY),
        m.Mahnstatus,
        ADDDATE(m.Mahn_datum, INTERVAL m.Faelligkeitstage DAY)
        ...

        
        >   
        
         lediglich den höchsten Mahnstatus UND das hierzu gehörende Mahndatum+Fälligkeit zu erhalten.  
          
         Über das Einbinden von MAX(m.Mahnstatus) in die WHERE-Klausel erhalte ich einen Fehler #1111 - Invalid use of group function.  
          
         Gruß, Stefan
        
        1. Tach!

          Über das Einbinden von MAX(m.Mahnstatus) in die WHERE-Klausel erhalte ich einen Fehler #1111 - Invalid use of group function.

          Das Maximum wovon? Ein Where schaut sich für den aktuellen Datensatz an, ob die Bedingungen passen. Wenn du dabei einen Maximalwert auswerten möchtest, musst du dazu eine komplette Subquery verfassen, die die zu beachtenden Datensätze berücksichtigt. Das ist auch dann notwendig, wenn das der Maximalwert aus Datensätzen der gerade abgefragten Tabelle ist. MySQL ist dabei nicht so frei und bildet selbst eine neue Datensatzmenge, um von ihr den gewünschten Wert zu ermitteln.

          lediglich den höchsten Mahnstatus UND das hierzu gehörende Mahndatum+Fälligkeit zu erhalten.

          Das geht sowie nicht besondern hübsch mit MAX(). MAX() ist eine GROUP-BY-Funktion. Ohne GROUP BY bezieht es sich auf alle Datensätze der Tabellen.

          Eine Abfrage SELECT *, MAX() FROM ... bringt dir nicht das gewünschte Ergebnis, weil die anderen Felder aus irgendeinem Datensatz genommen werden. (Andere DBMSe betrachten eine solche Abfrage als Fehler.) Du brauchst also eine Lösung ohne Gruppierfunktioin. Wie wär es mit absteigend sortieren und nur einen Datensatz nehmen? Das kannst du als Subquery in die FROM-Klausel schreiben.

          dedlfix.

          1. Wie wär es mit absteigend sortieren und nur einen Datensatz nehmen? Das kannst du als Subquery in die FROM-Klausel schreiben.

            Hi dedlfix,

            wie geht das?

              
            SELECT a,b,c FROM tabelle WHERE  
            SELECT ...  
            
            

            ?

            Oder habe ich Dich falsch verstanden?

            Stefan

            1. Tach!

              Wie wär es mit absteigend sortieren und nur einen Datensatz nehmen? Das kannst du als Subquery in die FROM-Klausel schreiben.
              wie geht das?

              Subquerys werden generell in ()-Klammern geschrieben. Sie liefern eine Ergebnismenge. Diese Ergebnismenge ist entweder ein einzelner skalarer Wert, dann kann man die Subquery an Stellen verwenden, wo auch andere Skalare stehen können (z.B. SELECT-Klausel oder als Vergleichswert in der WHERE-Klausel). Oder die Subqery ergibt eine Menge mit mehreren Zeilen und/oder Spalten, dann kann man die dort einsetzen, wo auch andere Mengen verwendbar sind. Ein Tabelle ist beispielsweise eine solche Menge. Das heißt, man kann in der FROM-Klausel nicht nur Tabellennamen sondern auch Subquerys als Datenlieferanten angeben. Der Rest ist Joinen, und das funktioniert wie Tabellen.

              dedlfix.

            2. Moin,

              wie geht das?

              Eine Subquery kann beispielsweise diese Struktur haben:

              SELECT * FROM ( SELECT a, b, c FROM x WHERE ... ) WHERE ...  
              
              

              Subquerys lassen sich aber prinzipiell vielseitig benutzen. Auch als Vergleichsmenge:

              SELECT a, b, c FROM x WHERE a IN (SELECT DISTINCT v FROM y WHERE f=g)  
              
              

              Grüße Marco