1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Limitierung einer "right join-abfrage"

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von bestella, 18 Dezember 2017.

  1. bestella

    bestella Benutzer

    Hello @ all,

    nach wie vor würde ich mich noch als neuling bezeichnen :) und als solcher habe ich eine Frage.

    Ich möchte gerne zwei Tabellen abfragen, wobei die eine quasi die quatität, der abzufragenden Werte vorgibt, und die Daten aus der anderen anhand der vorgaben vorgenommen werden sollen.

    Bildliches Beispiel zu besseren Verständniss darüber was hier eigentlich passieren soll:
    Es sollen quasi die Preise verschiedener Treibstoffe eines Anbieters, der letzten 24 Stunden ausgegeben werden. Hierbei sollen aus dem preisarchief die preise ausgelesen werden, die der preis-kategorie :pricecat (z.B. dieseltreibstoffe ...ist variabel) entsprechen. Bisher habe ich folgendes geschrieben.


    $sql = 'SELECT*FROM price
    RIGHT JOIN price_archive
    ON price.name = price_archive.name
    WHERE price.cat= :pricecat
    ORDER BY price_archive.name ASC LIMIT 24';


    PROBLEM:
    So wie ich das jetzt geschrieben habe, wird das Limit natürlich absolut auf 24 gesetzt. jedoch soll ja nur die Abfrage aus der Tabelle price_archive auf 24 limitiert werden, bevor er zum nächsten price weitergeht, um dann dessen Werte auszulesen.

    LG und Danke an alle Helfer im vorraus :)
     
  2. bestella

    bestella Benutzer

    edit: sry :pricecat steht für : pricecat (leerzeichen wegdenken) :)
     
  3. akretschmer

    akretschmer Datenbank-Guru

    Was Du suchst ist eine Abfrage nach den Top N per GROUP, was sich sehr gut über Window-Funktionen lösen läßt (rank(), dense_rank() oder auch row_number()) - was MySQL aber nicht kann.
     
  4. Chuky666

    Chuky666 Datenbank-Guru

    Hallo,


    mal so ins blaue geschossen... : würde eine Einschränkung im sinne von "datum between getdate() -24 h and getdate()" ? Also alles von jetzt bis 24h zurück?! Und das ergebnis dann mit deiner anderen tabelle joinen?!...Wie gesagt nur ein schuss ins blaue da infos recht wenig sind :)

    Viele Grüße
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Code:
    test=*# create table foo(cat int, price numeric);
    CREATE TABLE
    test=*# insert into foo select s%4, random()*100 from generate_Series(1, 20) s;
    INSERT 0 20
    test=*# select * from foo;
     cat |  price   
    -----+------------------
      1 | 43.5519861523062
      2 | 69.0027088858187
      3 | 84.7800165880471
      0 | 71.8519759364426
      1 |  65.803912980482
      2 | 17.6949787884951
      3 | 19.2791576962918
      0 | 77.0098157692701
      1 | 29.7842700500041
      2 | 57.5421118643135
      3 | 42.3636388033628
      0 | 84.9435252603143
      1 | 90.3366516344249
      2 | 27.6206892449409
      3 | 7.63921667821705
      0 | 58.7820012122393
      1 | 70.9931998047978
      2 | 31.6591657232493
      3 | 46.9018518459052
      0 | 34.8349587991834
    (20 Zeilen)
    
    und nun die 3 besten Preise je Categorie:

    Code:
    test=*# select cat, price from (select cat, price, row_number() over (partition by cat order by price) from foo) x where row_number <=3 order by cat, price;
     cat |  price   
    -----+------------------
      0 | 34.8349587991834
      0 | 58.7820012122393
      0 | 71.8519759364426
      1 | 29.7842700500041
      1 | 43.5519861523062
      1 |  65.803912980482
      2 | 17.6949787884951
      2 | 27.6206892449409
      2 | 31.6591657232493
      3 | 7.63921667821705
      3 | 19.2791576962918
      3 | 42.3636388033628
    (12 Zeilen)
    
    Code:
    
    
     
  6. bestella

    bestella Benutzer

    Hey, danke für eure Fixen Antworten ihr beiden,

    sry, ich versuche es nochmal ein wenig verständlicher zu formulieren :)

    Sagen wir wir haben verschiedene Treibstoffe (aus der tabelle price, welche den aktuellen Preis, welche jetzt gerade gilt ausgibt)

    Benzin
    Super
    Bleifrei
    Diesel
    kerosin
    usw.

    Usecase: Ein Mitarbeiter greift auf die Datenbank zu um die Preisentwicklungen in Verhältnis zueinander z.B. auszuwerten. Besagter Mitarbeiter ist für das Monitoren der drei Treibstoffe Benzin, Diesel & Kerosin zuständig und möchte eben diese ausgegeben bekommen. Dazu wird nun der aktuelle Preis aus der Tabelle "price" benötigt.

    Über einen Join sollen nun auch die Preise der letzten 24 Stunden ausgegeben werden, diese befinden sich in der Tabelle "price_archive", in jener werden die Preise alle 60 Minuten gespeichert. Aus dieser sollen nun die dem Mitarbeiter in der Tabelle "price" in der spalte "price.cat " zugeordneten Mitarbeiter ausgegeben werden. WICHTIG: es sollen natürlich nicht alle Preise ausgegeben werden, sondern eben n ur jene der letzten 24 Std. :)

    ...ich hoffe es war jetzt etwas verständlicher, ist aber auch kompliziert alles :D
     
  7. bestella

    bestella Benutzer

    Ich habe es nun anderweitig gelöst und werde mein ergebnis sobald etwas zeit ist an diser Stelle offenbaren :)

    ...danke an alle die mitgeholfen haben, ihr seid die besten! :*
     
  8. akretschmer

    akretschmer Datenbank-Guru

    wenn da zwei Tabellen sind, die die Preise enthalten, ist das auch nicht weiter kompliziert. Dann holst eben dort je Produkt die letzten N Preise raus.
     
  9. akretschmer

    akretschmer Datenbank-Guru

    ... wir sind gespannt.
     
  10. Chuky666

    Chuky666 Datenbank-Guru

    ich würde als erstes von der price_archive gruppiert nach name und price alle zeilen der letzen 24h holen. diese query als subquery joinen mit der price tabelle.
    bin auch gespannt vorallem ob man einen einblick in die architektur kriegt, klingt ein bissl abenteuerlich ;-)
     
  11. akretschmer

    akretschmer Datenbank-Guru

    Ich glaube, das ist nicht so einfach wie Du ( @Chuky666 ) grad denkst, aber egal, wir werden sehen ;-)

    Was ich vermute: eine externe Lösung, also z.B. PHP. Das paßt aber nicht zu anderen Postings des Fragestellers, wo es um *richtig viele* Datensätze ging, denn solch eine Frickellösung ist der direkte weg in die Performance-Hölle, aus der noch nie einer lebend rauskaum ...
     
    Chuky666 gefällt das.
  12. Chuky666

    Chuky666 Datenbank-Guru

    @akretschmer naja einfach ist es nie, aber da ich schon einige reports für unseren innendienst erstellt habe unter anderem auch n-preise der letzten monate für jeden artikel der im lager liegt um dann über den lieferanten eventuell geld zurückzufordern usw. denke ich schon das es einfach sein kann wenn die architektur stimmt :) aber genug geplappert bestella wird uns schon die lösung schlecht hin liefern :)
     
  13. bestella

    bestella Benutzer

    HAHA, ob das die Lösung schlecht hin ist, da bin ich mir nicht ganz sicher! :D
    ...es geht mittler Weile btw. nicht mehr um eine ganz so große Datenbak ...ein anderes Projekt. :)
     
  14. akretschmer

    akretschmer Datenbank-Guru

    dann bin ich beruhigt.
     
  15. bestella

    bestella Benutzer

    Btw. bevor hier jemand was falsches denkt, das hier mache ich nicht als bezahlte Auftragsarbeit, Datenbanken sin (zumindest aktuell noch) nicht mein Steckenpferd! :)

    Aaaaalso, ich mache das nun so, dass die dem jeweiligen User zugeordneten Treibstoffe in einem Array abgelegt werden. Anschließend werden diese dann in einer Schleife durchgearbeitet und zwar die jeweils 24 letzten Werte de jeweiligen, zu beobachtenden Objektes. Ob das nun so weltverändernd ist weiss ich nicht so genau! :D
    ...allerdings funktioniert es soweit :)

    <?php

    // Connect to Database
    $mysqli = getConnected();

    $i = 0;

    // repeat query 24times per monitoring-object (userObjects array is containing all user assigned monitoring-objects)
    while ( $i < count($userObjects) ) {

    $sql = 'SELECTname, price FROM price
    WHERE price.cat= : pricecat
    ORDER BY lastupdate DESCLIMIT24';
    $statement = $mysqli->query($sql);
    while ( $monitorObj = $statement->fetch_array() ) {

    // this is where magic happens

    };

    ++$i;

    }

    $mysqli->close();

    ?>
     
Die Seite wird geladen...

Diese Seite empfehlen