Ankündigung

Einklappen
Keine Ankündigung bisher.

Mehrere Arrays unterschiedlicher Größe kombinieren

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Mehrere Arrays unterschiedlicher Größe kombinieren

    Hi,

    ich komme mit meinem Problem einfach nicht weiter, irgendwie fehlt mir der Ansatz. Vereinfacht sieht es so aus:Ich lese drei Tabellen aus einer Datenbank aus und speicher diese Daten in drei Arrays, die alle eine MetaID und StationsID gemeinsam haben:

    Code:
    $CDT[0] = array('MetaID' => 1, 'StationID' => 1, 'CDT Daten' => 111);
    $CDT[1] = array('MetaID' => 1, 'StationID' => 2, 'CDT Daten' => 112);
    $CDT[2] = array('MetaID' => 1, 'StationID' => 3, 'CDT Daten' => 113);
    $CDT[3] = array('MetaID' => 2, 'StationID' => 1, 'CDT Daten' => 111);
    $CDT[4] = array('MetaID' => 2, 'StationID' => 2, 'CDT Daten' => 112);
    $CDT[5] = array('MetaID' => 2, 'StationID' => 3, 'CDT Daten' => 113);
    
    $CHEM[0] = array('MetaID' => 1, 'StationID' => 1, 'CHEM Daten' => 221);
    $CHEM[1] = array('MetaID' => 1, 'StationID' => 2, 'CHEM Daten' => 222);
    $CHEM[2] = array('MetaID' => 1, 'StationID' => 3, 'CHEM Daten' => 223);
    $CHEM[3] = array('MetaID' => 2, 'StationID' => 1, 'CHEM Daten' => 221);
    $CHEM[4] = array('MetaID' => 2, 'StationID' => 2, 'CHEM Daten' => 222);
    $CHEM[5] = array('MetaID' => 2, 'StationID' => 3, 'CHEM Daten' => 223);
    
    $BACT[0] = array('MetaID' => 2, 'StationID' => 1, 'BACT Daten' => 331);
    $BACT[1] = array('MetaID' => 2, 'StationID' => 3, 'BACT Daten' => 332);
    Im Ergebnis möchte ich eine Tabelle haben die so aussieht:

    Code:
    MetaID | StationsID | CDT Daten | CHEM Daten | BACT Daten
    1      |1           | 111       | 221        | 
    1      |2           | 112       | 222        | 
    1      |3           | 113       | 223        | 
    2      |1           | 111       | 221        | 331
    2      |2           | 112       | 222        | 
    2      |3           | 113       | 223        | 332
    Wie kann ich die Arrays entsprechend kombinieren?
    Ein weiterer Punkt ist: Ich weiß im Vorfeld nicht wie viele Tabellen ausgelesen werden müssen, es können 2, 3 oder auch 5 sein, die alle eine unterschiedliche Anzahl von Daten beinhalten können, aber immer die MetaID und die StationsID gemeinsam haben.


  • #2
    Hallo querfisch,

    ich sehe hier wieder mal einen Fall von "error by design". Solltest du die Programm-Logik noch ändern können, rate ich dir dringend dazu.

    Ein paar Gedanken dazu:
    - Für das Auslesen von ein oder mehreren Tabellen, sie kombiniert werden sollen verwendet der Programmierer JOINs um somit die Daten eines Datensatzes zusammen in einem Bereich zu haben
    - Die Ausgabe muss so generisch implementiert sein, dass sie anhand der Anzahl der Datensätze eine Tabelle erzeugt, die die Daten auch aufnehmen kann. Doe Überschriften dazu können entweder die Spalten-Namen sein, oder man mappt die Spalten-Namen nochmal auf "Anzeige-Namen".

    Grundsätzlich würde ich mich an deiner Stelle erst mal mit JOINs beschäftigen, die Ausgabe ist dann recht einfach.
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design before you start to write code!
    2. Discuss and review it together with experts!
    3. Choose good tools (-> Adventure PHP Framework (APF))!
    4. Write clean and reusable software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Kommentar


    • #3
      Hallo Dr.E.,

      mit JOINS habe ich es als erstes versucht. Das sah so aus:

      Code:
      SELECT * FROM metadata 
      
      LEFT JOIN cdt ON ( metadata.metaid = cdt.metaid )
      LEFT JOIN chemical ON ( metadata.metaid = chemical.metaid )
      LEFT JOIN chlorophyll ON ( metadata.metaid = chlorophyll.metaid )
      LEFT JOIN bacterioplankton ON ( metadata.metaid = bacterioplankton.metaid )
      LEFT JOIN pytop_data_total ON ( metadata.metaid = pytop_data_total.metaid )
      
      WHERE cdt.stationid IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80)
      AND cdt.stationid = chemical.stationid
      AND cdt.stationid = chlorophyll.stationid
      AND cdt.stationid = bacterioplankton.stationid
      AND cdt.stationid = pytop_data_total.stationid
      AND metadata.date BETWEEN "2003-08-01" AND "2005-01-31"
      Das Problem dabei ist, dass dann nicht alle Daten angezeit werden, denn die Bedingungen (gleiche MetaID und gleiche StationsID) wird ja nur für die geringste Menge der Datensätze erfüllt. In meinem oben geposteten Beispiel würde ich nur zwei komplette Datensätze erhalten. Wie kann ich das Statement denn so umwandeln, dass mir alle Daten angezeigt werden?

      Kommentar


      • #4
        Hallo querfisch,

        wie sieht denn deine Tabellen-Struktur aus? Ich kann deinem Design nicht ganz folgen...
        Viele Grüße,
        Dr.E.

        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        1. Think about software design before you start to write code!
        2. Discuss and review it together with experts!
        3. Choose good tools (-> Adventure PHP Framework (APF))!
        4. Write clean and reusable software only!
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        Kommentar


        • #5
          Die Tabellenstruktur sieht so aus:

          Code:
          MetaDaten:
          MetaID | Label | Date 
          
          Stationen:
          StationsID | Label | WaterDepth | Distance
          
          CDT:
          CDTID | StationsID | MetaID | Salinity | Temp | Density
          
          Chemical:
          CHEMID| StationsID | MetaID | Nitrate | Nitrite | Nitrate_Nitrite
          
          Bacterioplankton:
          BactID | StationsID | MetaID |Biovol | Abundance | Biomass
          
          usw.
          Also alle Tabellen enthalten als Fremdschlüssel die MetaID und die StationsID... Ob das die beste Lösung ist weiß ich nicht Ich lass mich da gerne eines Besseren belehren!

          Kommentar


          • #6
            Hallo querfisch,

            so kann man das schon grundsätzlich machen. Ich kenne deinen Anwendungsfall nicht weiter, deswegen kann ich das abschließend nicht beurteilen.

            Dein Ansatz ist erst mal OK. Lässt du die Einschränkungen weg, müsstest du alle Datensätze erhalten, die dem JOIN genügen. Ich nehme an, dass es an den Einschränkungen liegt. Vielleicht solltest du das letzte WHERE mal nach vorne ziehen, da es meinem Eindruck zufolge am stärksten einschränkt.

            Beginne mal mit den JOINs und nur einem WHERE und taste dich dann vor.
            Viele Grüße,
            Dr.E.

            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            1. Think about software design before you start to write code!
            2. Discuss and review it together with experts!
            3. Choose good tools (-> Adventure PHP Framework (APF))!
            4. Write clean and reusable software only!
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            Kommentar


            • #7
              so ein glück, dass du nur cdt.stationid von 1 bis 80 brauchst. was würdest du machen wenn da 200 wäre?
              Ich habe mir extra mühe gegeben und alle zahlen nachgeschaut und habe festgestellt, das du von 1 bis 80 keine lucken hast.

              where etwas >=1 and etwas <=80
              oder
              where etwsa between 1 and 80
              würde das gleiche bewirken.

              weiter kann ich dir leider nicht helfen, da ich nicht wirklich verstanden habe was du haben willst ( liegt bestimmt an mir).
              versuch aber deine bedingungen von Where in ON zu verlagern, sonnst wird es bei Leftjoin alles was mit where nicht stimmt abgeschnitten.
              Slava
              http://bituniverse.com

              Kommentar


              • #8
                ich glaube eher, dass LEFT JOIN einer der gesuchten lösungsbausteine ist.
                --

                „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                --

                Kommentar


                • #9
                  Thx Slava, das war die Lösung! Ich habe die Prüfung der StationsID nun in die ON-Statements verlagert und es funktioniert
                  Somit hat sich dann auch das Zusammenfügen der Arrays erledigt. Danke für eure Hilfe!

                  Code:
                  SELECT *
                  FROM metadata
                  LEFT JOIN cdt ON ( metadata.metaid = cdt.metaid )
                  LEFT JOIN chemical ON ( metadata.metaid = chemical.metaid
                  AND cdt.stationid = chemical.stationid )
                  LEFT JOIN chlorophyll ON ( metadata.metaid = chlorophyll.metaid
                  AND cdt.stationid = chlorophyll.stationid )
                  LEFT JOIN bacterioplankton ON ( metadata.metaid = bacterioplankton.metaid
                  AND cdt.stationid = bacterioplankton.stationid )
                  LEFT JOIN pytop_data_total ON ( metadata.metaid = pytop_data_total.metaid
                  AND cdt.stationid = pytop_data_total.stationid )
                  WHERE cdt.stationid
                  IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 )
                  AND metadata.date
                  BETWEEN "2003-08-01"
                  AND "2005-01-31"
                  Achso, das mit IN (StationID...) muss leider so sein, da man zuvor in einem Formular die Stationen wählen kann. Ok, wenn "Alle" angeklickt wurde ist where etwas >=1 and etwas <=80 wohl eleganter. Ansonsten muss ich aber mit den IDs arbeiten, da die Stationen aufgrund der Auswahr nicht immer fortlaufend sind

                  Kommentar


                  • #10
                    anstelle eines auswahlfeldes ein eingabe feld? ô.Ó
                    "Nobody is as smart as everybody" - Kevin Kelly
                    — The best things in life aren't things

                    Kommentar

                    Lädt...
                    X