Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Abfrage : Datum

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von helala_007, 10 Juni 2014.

  1. helala_007

    helala_007 Guest

    ich brauche bitte eure hilfe, ich habe versuche die SQL abfrage zu erstellen, aber die habe ich nicht geschafft ! kann mir vllt. jmd. dabei helfen ? danke sehr

    s.jpg s.jpg
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Ich denke, wir sind hier nicht unbedingt dazu da, Deine Semesterarbeiten oder sowas zu machen. Was ist denn Dein Ansatz?
     
  3. akretschmer

    akretschmer Datenbank-Guru

    Naja, damit Du nicht völlig im Regen stehst:

    Du hast:

    Code:
    test=*# select * from artikel ;
     a_id |  bezeichnung
    ------+-------------------
     4711 | koelsch wasser
     4712 | besseres wasser
     4713 | sehr gutes wasser
     4714 | spitzenwasser
    (4 rows)
    
    test=*# select * from art_preise ;
     id | artikel | gueltig_ab | preis
    ----+---------+------------+-------
      1 |  4711 | 2009-10-01 |  3.5
      2 |  4711 | 2010-01-01 |  3.69
      3 |  4712 | 2009-02-01 |  3.7
      4 |  4712 | 2009-12-12 |  3.85
      5 |  4714 | 2012-12-05 |  5.60
    (5 rows)
    
    Paßt. Wird, wie wir alle wissen, immer teuerer mit der Zeit ;-).

    Wichtig ist nun erst einmal, die gültigen Preise zu ermitteln:

    Code:
    test=*# select distinct on (artikel) artikel, gueltig_ab, preis from art_preise where gueltig_ab < current_date order by artikel, gueltig_ab desc;
     artikel | gueltig_ab | preis
    ---------+------------+-------
      4711 | 2010-01-01 |  3.69
      4712 | 2009-12-12 |  3.85
      4714 | 2012-12-05 |  5.60
    (3 rows)
    
    Das können wir nun mit den Artikel selber joinen:

    Code:
    test=*# select a.bezeichnung, p.gueltig_ab, p.preis from artikel a left join (select distinct on (artikel) artikel, gueltig_ab, preis from art_preise where gueltig_ab < current_date order by artikel, gueltig_ab desc) p on a.a_id=p.artikel;
      bezeichnung  | gueltig_ab | preis
    -------------------+------------+-------
     koelsch wasser  | 2010-01-01 |  3.69
     besseres wasser  | 2009-12-12 |  3.85
     sehr gutes wasser |  |
     spitzenwasser  | 2012-12-05 |  5.60
    (4 rows)
    

    Damit Du nicht nur Copy&Paste machst hab ich aber etwas eingebaut: das funktioniert NICHT mit MyZettelkasten, das kennt kein DISTINCT ON(). Aber mit etwas Fleiß bekommst das hin, Du willst ja auch was lernen.
     
  4. helala_007

    helala_007 Guest

    Hallo, nein das habe ich nicht im Studium.
    Ich habe für die nächsten Monate eine externe Kurs für. Und will mich vorher vorbereiten :).
    Kannst du mir bitte den code komplett geben ? Danke
    Liebe Gruß Jùliane
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Was willst Du komplett? Mein SQL ist komplett.
     
  6. helala_007

    helala_007 Guest

    Was ist mit ' distinct on '
     
  7. akretschmer

    akretschmer Datenbank-Guru

  8. helala_007

    helala_007 Guest

    Funktioniert leider nicht :(
     
  9. akretschmer

    akretschmer Datenbank-Guru

    Klar. Steht ja dort, daß das eine PG-Erweiterung ist. Eine recht praktische.

    Zeig doch mal, was Du so versucht hast.
     
  10. helala_007

    helala_007 Guest

    ich habe diesen code genommen :
    select a.bezeichnung, p.gueltig_ab, p.preis from artikel a left join (select distinct on (artikel) artikel, gueltig_ab, preis from art_preise where gueltig_ab < current_date order by artikel, gueltig_ab desc) p on a.a_id=p.artikel;
     
  11. akretschmer

    akretschmer Datenbank-Guru

    Ja, nee, is klar, ne?

    Das scheitert am DISTINCT ON (...), weil MySQL das nicht kann. Du wirst dieses innere Select umbauen müssen.

    Mit

    Code:
    test=*# select artikel, max(gueltig_ab) from art_preise where gueltig_ab < current_date group by artikel;
     artikel |  max
    ---------+------------
      4712 | 2009-12-12
      4711 | 2010-01-01
      4714 | 2012-12-05
    (3 rows)
    
    bekommst die Artikel und das letzte Datum. Nun willst aber noch den Preis haben. Das magische Zauberwort heißt: JOIN.
     
  12. ukulele

    ukulele Datenbank-Guru

    Man könnte es etwas umständlicher machen aber hätte dafür eine schöne Tabelle mit Zeitraum gültigvon / gültigbis auf deren Basis man recht banal filtern kann:
    Code:
    SELECT    *
    FROM    (
    SELECT    t1.id,
            t1.artikel,
            t1.preis,
            t1.gueltig_ab,
            t2.gueltig_ab AS gueltig_bis
    FROM    tabelle t1
    LEFT JOIN tabelle t2
    ON        t1.artikel = t2.artikel
    AND        t1.gueltig_ab < t2.gueltig_ab
    AND NOT EXISTS (
    SELECT    1
    FROM    tabelle
    WHERE    artikel = t2.artikel
    AND        gueltig_ab > t1.gueltig_ab
    AND        gueltig_ab < t2.gueltig_ab )
    ) t
    WHERE    getdate() BETWEEN t.gueltig_ab AND isnull(t.gueltig_bis,getdate())
    
     
  13. akretschmer

    akretschmer Datenbank-Guru

    Man könnte es aber auch einfacher machen in PostgreSQL mit Range-Typen und einem Exclusion Constraint, der verhindert, daß sich Gültigkeitszeiträume überschneiden. Man müßte es halt gleich richtig machen.
     
  14. ukulele

    ukulele Datenbank-Guru

    Nunja in der bisherigen Lösung besteht der "Komfort" ja darin, das man nur ein Datum eingeben muss, ab dem der Preis gilt. Da es zu keinem Zeitpunkt keinen Preis gibt, wäre ein "bis" Wert eigentlich redundant weil errechnbar.

    Aus Performance oder Übersichtsgründen mag man sich dann doch für Range Typen oder zwei Zeitspalten entscheiden, aber selbst mit diesem Wert: Die Anwendung oder die Datenbank sind dafür verantwortlich, das der richtige Preis zum richtigen Zeitpunkt ermittelt wird. Ein Exclusion Constraint ist da irgendwie überflüssig, wenn das gewährleistet wird.
     
  15. akretschmer

    akretschmer Datenbank-Guru

    Verhindere bitte dies:

    Code:
    test=*# create table preistabelle (produkt int, von text, bis text, preis int);
    CREATE TABLE
    Time: 15,187 ms
    test=*# insert into preistabelle values (1, 'vorgestern', 'übermorgen', 2);
    INSERT 0 1
    Time: 0,339 ms
    test=*# insert into preistabelle values (1, 'gestern', 'morgen', 1);
    INSERT 0 1
    Time: 0,177 ms
    
    Welcher Preis gilt heute? Mal so als Demo (mit falschen Datentypen). Das zu verhindern ist weder via Applikation noch DB trivial, solange Du keine Exclusion Constraints hast, die das faktisch durch einen UNIQUE INDEX dann erzwingen.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden