Abfrage : Datum

H

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
 
Werbung:
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.
 
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
 
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;
 
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;

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.
 
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())
 
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:

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.
 
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.
 
Werbung:
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.

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.
 
Zurück
Oben