Ankündigung

Einklappen
Keine Ankündigung bisher.

Preiszuordnung nach Paketgewicht / Lösung in PHP-Logik oder MySQL-Query?

Einklappen

Neue Werbung 2019

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

  • Preiszuordnung nach Paketgewicht / Lösung in PHP-Logik oder MySQL-Query?

    Liebe PHP-Gemeinde,

    seit mehreren Tagen und diversen Ansätzen habe ich mich nun (mal wieder) dazu entschlossen hier im Forum nach Unterstützung zu fragen.
    Ich stehe vor folgender Problematik:

    Ich vesende Pakete in unterschiedlichen Größen und Gewichten und möchte anhand des Gewichts den Preis bei meinen gelisteten Dienstleister anzeigen lassen.

    Beispiel:
    Bis 3 kg kostet das Paket 2,50 €
    Ab 3,0 kg bis 5,0 kg kostet das Paket 3,00 €
    Ab 5,0 kg kostet das Paket 4,50 €

    Nun kann es sein, dass ich zwei Pakete versenden möchte. Das erste mit 3 kg, das zweite mit 6,5 kg. Was folglich bedeutet, dass erste Paket kostet 2,50 €, das 2. dann 4,50 €.
    So muss ich bei jedem Paket das Gewicht und den Preis beim jeweilgen Dienstleister prüfen.

    Folgende Ansätze habe ich versucht:

    1. MySQL-Query: Kompletter FAIL!!! Egal welchen Ansatz ich in einer Query mit DISTINCT,BETWEEN, LIMIT etc versucht habe, brachte keine Lösung und ich müsste mich an dieser Stelle schämen, wenn ich die Codes posten würde.

    Aufgrund dieser Niederlagen muss wohl die Lösung im PHP-Code in einer Schleife liegen. Und nun mein Aktueller Ansatz:

    Meine Funktion (Klassenfunktion):
    PHP-Code:
    public static function getPaketPreis($idDienstleister){
    $sql "SELECT * FROM preisliste WHERE idDienstleister = :idDienstleister";

    $query DB::select($sql,[':idDienstleister' => $idDienstleister]);

    return 
    $query;

    Diese Funktion gibt mir die Gewicht und Preise für den jeweiligen Dienstleister aus.

    Und nun komm ich an den Punkt, wo ich nun um moralische und geistige Unterstützung bitte:

    Meine Schleife
    PHP-Code:

    $d 
    Dienstleister::getPaketPreis(4);

    foreach(
    $d as $paketpreis){

       if(
    $paketpreis['gewicht'] <  $dasPaketGewicht){

                         
    //ja und jetzt?           

       
    }


    Wie schaffe ich es, dass bei einem 3,5kg schweren Paket mir der Preis von 3,50 € angezeigt wird?

    Ich bin um jeden Link (den ich nicht gefunden habe), bzw. Ratschlag oder eventuell auch einen Lösungsansatz dankbar.

    Vielen Dank jetzt schon fürs Lesen und Gedanken machen.




  • #2
    MySQL-Query: Kompletter FAIL!!! Egal welchen Ansatz ich in einer Query mit DISTINCT,BETWEEN, LIMIT etc versucht habe, brachte keine Lösung und ich müsste mich an dieser Stelle schämen, wenn ich die Codes posten würde.
    Das hilft nur leider nicht beim Helfen. Denn an sich ist so ein Vergleich in SQL nicht besonders schwer (CASE, IF), vorausgesetzt die Spalte hat den richtigen Datentyp.

    Kommentar


    • #3
      Vielen Dank für die erste Reaktion Dormilich!

      Wenn ich ehrlich bin, hab ich CASE noch nie in einer Mysql-Query versucht.

      Nun ist es so, dass ich bei keinem Dienstleister die gleichen "Gewichtsbereiche" habe. Vom aktuellen Verständnis würde das eine gigantische Query geben, oder?

      Wenn ich die Aussage "Wenn das Gewicht größer als 3 kg und kleiner ALS DIE NÄCHSTE "Gewichtsgrenze" ist, dann nimm den Preis der höheren "Gewichtsgrenze" in einer Query formulieren möchte, sollte ich das direkt in MySQL machen?

      Kommentar


      • #4
        Warum nicht einfach von - bis und dann BETWEEN?

        The string "()()" is not palindrom but the String "())(" is.

        Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
        PHP.de Wissenssammlung | Kein Support per PN

        Kommentar


        • #5
          Nun ist es so, dass ich bei keinem Dienstleister die gleichen "Gewichtsbereiche" habe.
          Dann mach eine Tabelle dafür, sodass du gleich den Preis joinen kannst.

          Wenn das Gewicht größer als 3 kg und kleiner ALS DIE NÄCHSTE "Gewichtsgrenze" ist
          ... dann fängt mann immer mit der höchsten Grenze an zu testen und arbeitet sich nach unten durch. Ist aber bei einer eigenen Tabelle für die Gewichtsgrenzen kein Problem, da das ja gerade Bestandteil der Join Condition ist.

          Kommentar


          • #6
            @hausl: Den Gedankenansatz hatte ich auch, aber hier scheitert es an meiner Umsetzung.

            Meine Query:

            PHP-Code:
            SELECT FROM preisliste
            WHERE idDienstleister 
            1
            AND gewicht
            BETWEEN min
            (gewicht) AND max(gewicht
            So habe ich ja nur die linke und rechte Grenze der Gewichte. Für 3.5 habe ich expliziert keinen Wert in der Tabelle hinterlegt.


            @Dormilich: Ist das die Richtung, die Du vorschlägst?
            https://dba.stackexchange.com/questi...-in-one-select

            Danke für Eure Unterstützung

            Kommentar


            • #7
              Falls mal jemand ein ähnliches Problem, aber PostgreSQL als DB hat: da bieten sich natürlich massiv die RANGE-Typen an.

              Code:
              test=*# create table packetpreise (dienstleister int, gewicht numrange, preis numeric, exclude using gist(dienstleister with =, gewicht with &&));
              CREATE TABLE
              test=*# insert into packetpreise values (1, '[0,3)',2.5);
              INSERT 0 1
              test=*# insert into packetpreise values (1, '[3,5)',3.0);
              INSERT 0 1
              test=*# insert into packetpreise values (1, '[5,)',4.5);
              INSERT 0 1
              test=*# insert into packetpreise values (2, '[0,2)',2.4);
              INSERT 0 1
              test=*# insert into packetpreise values (2, '[2,4)',2.2);
              INSERT 0 1
              test=*# insert into packetpreise values (2, '[4,8)',2.0);
              INSERT 0 1
              test=*# insert into packetpreise values (2, '[8,)',1.5);
              INSERT 0 1
              
              test=*# select * from packetpreise ;
               dienstleister | gewicht | preis
              ---------------+---------+-------
                           1 | [0,3)   |   2.5
                           1 | [3,5)   |   3.0
                           1 | [5,)    |   4.5
                           2 | [0,2)   |   2.4
                           2 | [2,4)   |   2.2
                           2 | [4,8)   |   2.0
                           2 | [8,)    |   1.5
              (7 Zeilen)
              
              test=*# select dienstleister,preis from packetpreise where gewicht @> 4.0;
               dienstleister | preis
              ---------------+-------
                           1 |   3.0
                           2 |   2.0
              (2 Zeilen)
              Da kommt dann auch der Index zum Einsatz, daher wird das auch sehr flott sein:

              Code:
              test=*# explain analyse select dienstleister,preis from packetpreise where gewicht @> 4.0;
                                                                                 QUERY PLAN                                                                   
              ------------------------------------------------------------------------------------------------------------------------------------------------
               Bitmap Heap Scan on packetpreise  (cost=4.17..12.63 rows=4 width=36) (actual time=0.030..0.031 rows=2 loops=1)
                 Recheck Cond: (gewicht @> 4.0)
                 Heap Blocks: exact=1
                 ->  Bitmap Index Scan on packetpreise_dienstleister_gewicht_excl  (cost=0.00..4.17 rows=4 width=0) (actual time=0.016..0.016 rows=2 loops=1)
                       Index Cond: (gewicht @> 4.0)
               Planning time: 0.099 ms
               Execution time: 0.078 ms
              (7 Zeilen)
              
              test=*#
              PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

              Kommentar


              • #8
                Zitat von groovemachine Beitrag anzeigen
                @hausl: Den Gedankenansatz hatte ich auch, aber hier scheitert es an meiner Umsetzung.
                Ich meinte eher so.. mit dem "Nachteil" das du auch Obergrenzen erfassen musst. Und ev. mit Kommastellen arbeiten, wenn es zB genau 3 kg sind. (zB. bis 3kg und dann ab 3.001 kg). Aber das Prinzip dürfte klar sein, der Rest ist finetuning.
                Code:
                dienstleister | gewicht_von | gewicht_bis | preis
                 1              0             3             2.5
                 1              3             5             3.0
                 1              5             99999         4.5
                 2              0             2             2.4
                 2              2             4             2.8
                 2              4             8             3.0
                 2              8             99999         5.0
                Code:
                SELECT dienstleister, preis
                FROM ...
                WHERE
                  gesuchtes_gewicht BETWEEN gewicht_von AND gewicht_bis
                ORDER BY preis ASC
                Dann bekommst du alle Dienstleister, kannst die dann nach "billig/aufsteigend" (ASC) sortieren (ORDER BY) und den ersten nehmen bzw. mit LIMIT 1 gleich reduzieren wobei du bei gleichen Preisen dann halt immer einen "verlierst".

                LG
                The string "()()" is not palindrom but the String "())(" is.

                Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                PHP.de Wissenssammlung | Kein Support per PN

                Kommentar


                • #9
                  So erstmal DANKE an alle, die mich hier so geduldig unterstützt haben.

                  DANKE hausl! Nach Deinem Ansatz habe ich es nun endlich geschafft es umzusetzten. Vielen vielen Dank! Endlich wieder normale Nächte

                  Kommentar

                  Lädt...
                  X