Ankündigung

Einklappen
Keine Ankündigung bisher.

query von allen datensätze alle kunden jeweils der neueste eintrag...

Einklappen

Neue Werbung 2019

Einklappen
Dieses Thema ist geschlossen.
X
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • query von allen datensätze alle kunden jeweils der neueste eintrag...

    Hi,

    überlege gerade wie ich das anstellen kann.
    ich hab in einer tabelle viele,viele log-einträge von mehreren kunden..

    ich bräuchte nun von jedem kunden nur den jeweils neusten datensatz.
    das könnte man ja ganz leicht lösen indem man prüft welcher timestamp jeweils am nächsten zum aktuellen datum liegt.
    EDIT: mhh so lässt sich das wohl nicht so einfach lösen... oder wie könnte ich "am nächsten an" schreiben? <> is ja nix ^^

    und wie bekomme ich von jedem kunden nur einen eintrag?

    hab das bisher mit distinct gelöst: (datumdingens ist noch nicht drin)

    aber.. das scheint mir nicht ganz korrekt... oder?

    PHP-Code:
    SELECT     DISTINCT sofa.t_kunden.f_kdname AS kdname,
                                    
                                    
    serverstat.t_cms.f_version AS cms,
                                    
    serverstat.t_ims.f_version AS ims
                                    
                                    FROM t_data
                                    
                                    INNER JOIN serverstat
    .t_cms ON serverstat.t_data.f_cms_id serverstat.t_cms.f_id
                                    INNER JOIN serverstat
    .t_ims ON serverstat.t_data.f_ims_id serverstat.t_ims.f_id
                                    INNER JOIN sofa
    .t_kunden ON serverstat.t_data.f_idkunde sofa.t_kunden.f_idkunde
                                    INNER JOIN sofa
    .t_customer_datafields ON serverstat.t_data.f_idkunde sofa.t_customer_datafields.f_idkunde
                                    
                                    WHERE     serverstat
    .t_data.f_idkunde $sqlkunde
                                        
    AND sofa.t_customer_datafields.f_label 'Projektliste'
                                        
    AND sofa.t_customer_datafields.f_value like '" . $sqlprolist . "'
                                        
                                    
    $sqlsort 


  • #2
    Stichwort: Korrelierte Unterabfrage

    Kommentar


    • #3
      Kleines allgemeines Beispiel mit Kundenlog und Kundenstamm:

      Code:
      CREATE TABLE kundenlog (
       id INT NOT NULL,
       kunde_id INT NOT NULL,
       zeit TIMESTAMP NOT NULL
      );
      
      CREATE TABLE kunde(
       kunde_id INT NOT NULL,
       name VARCHAR(50) NOT NULL
      );
      
      -- Kunde und letzter Timestamp
      SELECT kunde_id, MAX(zeit) AS zeit
        FROM kundenlog
       GROUP BY kunde_id;
      
      
      -- Kundenliste mit Name und letztem Timestamp
      SELECT k.name, k1.zeit
        FROM kunde k
        JOIN (SELECT kunde_id, MAX(zeit) AS zeit
                FROM kundenlog
               GROUP BY kunde_id) k1
          ON k1.kunde_id = k.kunde_id
      ORDER BY k.name;
      Liefert für jeden Kunden einen Datensatz mit dem neuesten Timestamp.

      Grüße
      Thomas

      Kommentar


      • #4
        dank euch... das beispiel von thomas ist wenigstens nah an meinem.. da kapier ich diese unterabfragen endlich ^^ im gegensatz zu google


        danke!

        Kommentar


        • #5
          ok.. ich hätte trotzdem noch eine frage

          den timestamp liest er richtig aus (also der letzte von jedem kunden...)

          aber: die cms_version und ims version stimmt nicht mit dem überein was rauskommen sollte... die id's in den jeweils letzten datensätzen sind nicht die die beim letzten datensatz drinstehen..


          PHP-Code:
          SELECT     sofa.t_kunden.f_kdname AS kdname,
                                          
                                          
          data.cms,
                                          
          data.ims,
                                          
          data.time
                                          
                                          FROM sofa
          .t_kunden
                                          JOIN 
          (SELECT t_data.f_idkundeMAX(t_data.f_timestamp) as timet_cms.f_version as cmst_ims.f_version as ims
                                                  FROM t_data
                                                  INNER JOIN t_cms ON t_data
          .f_cms_id t_cms.f_id
                                                  INNER JOIN t_ims ON t_data
          .f_ims_id t_ims.f_id    
                                          
                                                  GROUP BY t_data
          .f_idkundedata
                                                  ON data
          .f_idkunde sofa.t_kunden.f_idkunde
                                                  
                                                                  
                                          INNER JOIN sofa
          .t_customer_datafields ON data.f_idkunde sofa.t_customer_datafields.f_idkunde
                                          
                                          WHERE     data
          .f_idkunde $sqlkunde
                                              
          AND sofa.t_customer_datafields.f_label 'Projektliste'
                                              
          AND sofa.t_customer_datafields.f_value like '" . $sqlprolist . "'
                                                                                  
                                          
          $sqlsort 

          Kommentar


          • #6
            Hi,

            @thomas_w: Wozu die Unterabfrage? Ohne würde es doch auch funktionieren..

            Kommentar


            • #7
              Zitat von Thalo Beitrag anzeigen
              @thomas_w: Wozu die Unterabfrage? Ohne würde es doch auch funktionieren..
              Beispiel?

              MySQL erlaubt (sich) beim GROUB BY diverse Dinge, die nichts mehr mit dem SQL-Standard zu tun haben.

              Grüße
              Thomas

              Kommentar


              • #8
                Zitat von thomas_w Beitrag anzeigen
                Beispiel?

                MySQL erlaubt (sich) beim GROUB BY diverse Dinge, die nichts mehr mit dem SQL-Standard zu tun haben.

                Grüße
                Thomas
                Hi,

                also bei mir funktioniert ein : SELECT .., MAX(zeit) FROM 1 INNER JOIN 2 ... ebenfalls. Ob es dem Standard entspricht weiß ich nicht.

                Kommentar


                • #9
                  Zitat von taurus Beitrag anzeigen
                  aber: die cms_version und ims version stimmt nicht mit dem überein was rauskommen sollte... die id's in den jeweils letzten datensätzen sind nicht die die beim letzten datensatz drinstehen..
                  Die Frage habe ich nicht wirklich verstanden...

                  Der GROUP BY ist nicht vollständig (auch wenn MySQL dies erlaubt). Wenn ein GROUP BY genutzt wird, muss auf alle anderen Spalten, die nicht im GROUP BY Prädikat sind, eine Aggregatfunktion wie MIN(), MAX(), COUNT() angewendet werden.

                  Code:
                  ...
                    JOIN (SELECT t_data.f_idkunde, MAX(t_data.f_timestamp) as time, 
                                 MAX(t_cms.f_version) as cms, 
                                 MAX(t_ims.f_version) as ims
                            FROM t_data
                            INNER JOIN t_cms ON t_data.f_cms_id = t_cms.f_id
                            INNER JOIN t_ims ON t_data.f_ims_id = t_ims.f_id    
                            GROUP BY t_data.f_idkunde
                          ) data
                  ...
                  Grüße
                  Thomas

                  Kommentar


                  • #10
                    bsp: der neueste datensatz aus t_data von kunde mit der idkunde 1 hat als cms_id die 1 und ims die 2 ....

                    nun liest er mir aber nicht die version in t_cms aus, wo cms_id = 1 sondern irgendeinen anderen.. gleiches für ims

                    soll heißen in dem neusten datensatz (max timestamp) stimmt die cms/ims version nicht (cms_id von t_data ist nicht cms_id von t_cms)

                    ( in t_Data steht ja nur die id drin nicht der versionsname.... )


                    wenn ich das machen würde wie du beschrieben hast (MAX(t_cms.f_version) würde ich ja die höchste version bekommen die in t_cms gespeichert ist... aber nicht die version die im neusten datensatz für den kunden xy gespeichert ist.


                    soweit verstanden?
                    ich brauch also vom letzten datensatz für jeweils alle kunden die info welche cms version aktuell läuft (also muss er nach der id die in t_data gespeichert ist in t_cms suchen,, inner join eben..)


                    EDIT: gibts nich ein WHERE timestamp = MAX(timestamp) und das pro kunde? sprich dass er von jedem kunden jeweils den letzten datensatz ausliest... ? werd auch mal das von Thalo probieren.. aber erst später.. jetzt erstmal noch das schöne wetter genießen

                    Kommentar


                    • #11
                      Ich denke, dazu muss der GROUP BY in einen eigenen SUB-Select t_data_max wandern, um für jede f_idkunde den maximalen f_timestamp zu bekommen. Die JOIN zwischen den Tabellen können dann eventuell so aussehen..

                      Code:
                      ...
                      JOIN (SELECT t_data.f_idkunde, MAX(t_data.f_timestamp) AS f_timestamp 
                              FROM t_data
                             GROUP BY t_data.f_idkunde) t_data_max
                      JOIN t_data
                        ON t_data.f_timestamp = t_data_max.f_timestamp
                       AND t_data.f_idkunde = t_data_max.f_idkunde
                      JOIN t_cms 
                        ON t_data.f_cms_id = t_cms.f_id
                      JOIN t_ims 
                        ON t_data.f_ims_id = t_ims.f_id 
                      ...
                      Grüße
                      Thomas

                      Kommentar


                      • #12
                        so, funktioniert nun so wie es soll... ich lese jetzt hier nur die cms, ims version aus und die server ip.-.. das erste query ist soweit fertig.

                        anbei der quellcode:
                        PHP-Code:
                        SELECT sofa.t_kunden.f_kdname AS kdname,
                                                        
                                                        
                        t_cms.f_version as cms,
                                                        
                        t_ims.f_version as ims,
                                                        
                        t_server.f_ip as serverip
                                                        
                                                        FROM t_data
                                                        JOIN 
                        (SELECT t_data.f_idkunde as id,
                                                        
                        MAX(t_data.f_timestamp) as time
                                                        FROM t_data
                                                                    
                                                        GROUP BY t_data
                        .f_idkundet_data_max ON t_data.f_idkunde t_data_max.id 
                                                        
                        AND t_data.f_timestamp t_data_max.time
                                                    
                                                        JOIN t_cms ON t_data
                        .f_cms_id t_cms.f_id
                                                        JOIN t_ims ON t_data
                        .f_ims_id t_ims.f_id
                                                        JOIN t_server ON t_data
                        .f_idkunde t_server.f_idkunde
                                                        JOIN sofa
                        .t_customer_datafields ON t_data.f_idkunde sofa.t_customer_datafields.f_idkunde
                                                        JOIN sofa
                        .t_kunden ON t_data.f_idkunde sofa.t_kunden.f_idkunde
                                                        
                                                        WHERE     t_data
                        .f_idkunde $sqlkunde
                                                            
                        AND sofa.t_customer_datafields.f_label 'Projektliste'
                                                            
                        AND sofa.t_customer_datafields.f_value like '" . $sqlprolist . "'
                                                                                                
                                                        
                        $sqlsort 
                        passt oder?


                        noch eine frage.... wollte das ganze grad in explain eingeben.. abbbberr ich kann nicht mehr als 3 zeilen eingeben.. d.h. das query passt nicht rein... was soll ich denn nur tun?



                        PS.: ich baue heute und morgen zwei zwei andere queries.. sollten in kürze fertig sein
                        wird ne interessante geschichte... was z.b. das alter der letzten glog, chlog einträge angeht (die werden am ende rot, gelb, grün eingefärbt... und eiiiigentlich habe ich pro server unterschiedliche max_times.. aber ich werde hier wohl eine allgemein gültige legende nutzen (d.h. alle maxtimes gleich für alle server..)


                        wenns dich interessiert kann ich dir gerne nen kompletten dump der datenbank schicken... momentan 10MB

                        Kommentar


                        • #13
                          Zitat von taurus Beitrag anzeigen

                          noch eine frage.... wollte das ganze grad in explain eingeben.. abbbberr ich kann nicht mehr als 3 zeilen eingeben.. d.h. das query passt nicht rein... was soll ich denn nur tun?
                          Verstehe ich nicht wirklich. In die MySQL-Console passt jede Menge rein.

                          Code:
                          mysql> EXPLAIN SELECT ....
                          Was den Datenbank-Dump angeht, wären mir einzelne, gut aufbereitete Fragen plus ein paar Testdaten lieber.

                          Grüße
                          Thomas

                          Kommentar


                          • #14
                            stimmt.. alles in eine zeile geht nicht, mit absatz gehts

                            wenn du die daten die momentan in der db liegen haben willst sag bescheid (werde dir dann nur so 10.000 oder 5.000 davon schicken...)

                            ich hab anbei mal das query mit zwei unterschiedlichen abfragen gefüllt.. einmal alle server einmal nur von einer bestimmten kette.

                            "derived2" verstehe ich im explain nicht was ist das?
                            außerdem: idkunde ist ja sowohl in serverstat.t_data als auch in der datenbank sof enthalten. an der sof a datenbank werde ich nichts ändern (eine komplette umstruktierung der datenbank hätte wahrscheinlich fatale folgen.. außerdem ist das skript alt(läuft nur unter php4,mysql4) und updaten ist nicht mehr da von unserer seite aus schon zuviel dran gemacht wurde...)

                            aber ein index für f_idkunde scheint mir nicht verkehrt....

                            was meinst du?
                            Angehängte Dateien

                            Kommentar


                            • #15
                              das <derived2> kommt vom

                              Code:
                              ..
                              JOIN (SELECT t_data.f_idkunde as id,
                              MAX(t_data.f_timestamp) as time
                              FROM t_data
                              GROUP BY t_data.f_idkunde)
                              ..
                              soweit okay, bis auf die Tatsache, dass dabei keinerlei Index verwendet werden.

                              Als Sofortlösung hilft folgender Index:

                              Code:
                              CREATE INDEX sx_t_data_01 ON t_data ( f_idkunde, f_timestamp);
                              Sofern nicht bereits ein solcher existiert.

                              Das Hauptproblem ist derzeit die Tabelle t_data. Kannst du mir dazu das aktuelle CREATE TABLE t_data... plus alle Index posten bzw. den EXPLAIN mit dem neuen Index beilegen?

                              Grüße
                              Thomas

                              Kommentar

                              Lädt...
                              X