![]() |
Datenbank: MSSQL • Version: 2000 • Zugriff über: BDE
Artikelpreis zu gegenem Datum
Irgendwie häng ich ganz blöd bei einer SQL Abfrage.
Ich habe eine Tabelle Artikel, mit Feldern ID und Bezeichnung Und eine Tabelle mit den aktuellen Artikelpreisen: ID, Artikel, Preis, Datum Soll heissen, im Laufe der Zeit kann sich ein Artikelpreis ändern. Das Datum in der Preis Tabelle ist der Wert, ab wann der angegebene Preis gültig ist. Bsp: Artikel 1, 'Blubb' Preise: 1, 1, 100, 01.01.2005 2, 1, 200, 01.01.2006 3, 1, 300, 01.01.2007 Ich brauche jetzt eine Liste mit allen Artikeln und allen korrekten Preisen zu einem gegebenem Datum, z.B. 01.02.2006. Ich krieg das nicht hin. Ältere Preise krieg ich leicht weggefiltert, da ja das Suchdatum >= Preisdatum sein muss. Aber ich krieg den Eintrag 01.01.2007 mit Preisangabe 300 nicht weg aus dem Resultset. |
Re: Artikelpreis zu gegenem Datum
hi jelly,
du möchtest eine liste mit all deinen produkten haben, wo bei jedem produkt der preis eines bestimmten datums ist? ich würde jetzt mal spontan folgendes vorschlagen:
SQL-Code:
sollte doch funktionieren oder nicht?
SELECT a.Name, p.Preis
FROM artikel AS a LEFT JOIN preise AS p ON p.Artikel = a.ID WHERE p.Datum = '01.01.2006' aeno |
Re: Artikelpreis zu gegenem Datum
Zitat:
SQL-Code:
Das sollen alle Artikel mit ihrem zum 01.01.2006 gültigen Preis sein, wenn ich das nicht total verkorkt hab.
SELECT a.Name, p.Preis
FROM artikel AS a, preise AS p WHERE p.Artikel = a.ID AND p.Datum = MAX(SELECT p.Datum from artikel AS a, preise AS p where p.artikel = a.ID and p.Datum <= '01.01.2006') |
Re: Artikelpreis zu gegenem Datum
Nee das wird so einfach nicht funktionieren, da ja nicht jeden Tag der gültige Preis eingetragen wird. Das heißt man muss die letzte Aktualisierung vor dem Datum berücksichtigen.
Sowas könnte funktionieren:
SQL-Code:
Das sollte dir das gewünschte Ergebnis liefern. (hoffe ich :))
DECLARE @Suchdatum datetime;
SET @Suchdatum = '01.01.2006' SELECT a.Name, p.Preis FROM artikel AS a LEFT JOIN preise AS p ON p.Artikel = a.ID WHERE p.Datum <= @Suchdatum AND p.Datum = (SELECT max(preise.Datum) FROM preise WHERE preise.Artikel = a.ID AND preise.datum <= @Suchdatum) |
Re: Artikelpreis zu gegenem Datum
:spin2: zwei doofe ein Gedanke - und du warst schneller...
|
Re: Artikelpreis zu gegenem Datum
:dancer2:
|
Re: Artikelpreis zu gegenem Datum
Ha aber deins wird nicht funktionieren :-D
Hier nämlich greifst du nicht mehr auf die ursprüngliche Artikel-Tabelle zu:
SQL-Code:
Du suchst damit nämlich einfach nur das maximale datum für alle Artikel raus und nicht für dein einen ;-)
AND p.Datum = MAX(SELECT p.Datum from artikel AS a, preise AS p where p.artikel = a.ID and p.Datum <= '01.01.2006')
:dancer: |
Re: Artikelpreis zu gegenem Datum
Zitat:
Aber warum machst du zwei mal "<=@Suchdatum" :?: |
Re: Artikelpreis zu gegenem Datum
Stimmt kann man weglassen (das obere). Das untere brauchst du, damit du das richtige "maximale" Datum raussuchst.
|
Re: Artikelpreis zu gegenem Datum
Also irgendwie kommt das noch nicht ganz hin. Ich habs aber jetzt über eine temporäre View gelöst. Eure Ansätze waren schon alle richtig, nur muss ich noch ein weiteres Kriterium berücksichtigen.
Aber jetzt scheints auch bei mir zu klappen... Danke für die Mühe. |
Re: Artikelpreis zu gegenem Datum
Ich würde den Einsatz einer SP in Betracht ziehen, z.B. so :
SQL-Code:
Da gehts zwar um die Ermittlung der Mwst., aber das dürfte egal sein. Es ist halt datumsgesteuert. Ob Mickysoft-SQL allerdings so was hat wie SELECT FIRST ? :gruebel: In Firebird gibts das auch erst seit vorletzter Version.
ALTER PROCEDURE NETTOSP (
BETRAG DECIMAL(15,2), MWSTSATZ SMALLINT, DATUM DATE) RETURNS ( GESNETTO DECIMAL(15,2)) AS DECLARE VARIABLE MWSTPROZ DECIMAL(15,2); BEGIN SELECT FIRST 1 MWSTWERT FROM MWST WHERE (MWSTSATZ=:MWSTSATZ) AND (ABDATUM <= :DATUM) ORDER BY ABDATUM DESC INTO :MWSTPROZ; IF (MWSTPROZ IS NULL) THEN MWSTPROZ = 0; /* GESNETTO = CAST (BETRAG / (1 + MWSTPROZ / 100) AS DECIMAL (15,2)); */ GESNETTO = BETRAG / (1 + MWSTPROZ / 100); SUSPEND; END |
Re: Artikelpreis zu gegenem Datum
Zitat:
|
Re: Artikelpreis zu gegenem Datum
Zitat:
FB scheint sich mit jedem bisschen was sie von Interbase rausschmeißen zu verbessern. ;) @Topic Eine selectable Procedure wäre hier nun wirklich witzlos, auch wennn SQL ziemlich schnell ziemlich eklig wird, wenn es um Aggregationen geht. (hässlich ist es ja sowieso immer ;) ) Als Erbchleicher wäre wahrscheinlich eine Liste der Ids aller Preise ausreichend um bereits vorher geholte Instanzen der Preise wiederzufinden:
SQL-Code:
Als RADieschen braucht man mehr Spalten, wodurch die Gruppierung aufwendiger wäre als die SubQuery aus Dominiks Beispiel. (MSSQL hatte vor 2005 leider den Hang dazu, SubQueries gerne mal für jeden Datensatz zu neu abzufragen :? )
SELECT p.Id
FROM Artikel a INNER JOIN Preise p ON p.Artikel = a.ID INNER JOIN Preise filter ON p.Artikel = a.ID WHERE filter.Datum <= @Suchdatum GROUP BY p.Id, p.Datum HAVING p.Datum = max(filter.Datum) |
Re: Artikelpreis zu gegenem Datum
Zitat:
|
Re: Artikelpreis zu gegenem Datum
Zitat:
|
Re: Artikelpreis zu gegenem Datum
Zitat:
Ich hab mir als Erstes eine temporäre View erstellt:
SQL-Code:
Für die eigentlich Abfrage greif ich dann über joins auf diese View zu, weil ich noch aus anderen Tabelle etliches Zeusch brauch. Aber im Grunde ist obige temporäre View schon das, was das Problem löst.
create view vwPreiseHeuteTemp
as SELECT fiArtikel, ISNULL(MAX(Datum), GETDATE() AS Datum, EKVK FROM dbo.Preise WHERE (Datum <= GETDATE()) GROUP BY fiArtikel, EKVK HAVING (MAX(Datum) <= GETDATE()) |
Re: Artikelpreis zu gegenem Datum
Du kannst es auch so lösen:
SQL-Code:
Die ORDER BY Klausel macht die Abfrage langsam. Wenn Du einen Clustered Index auf Preise.Datum setzt, ist die Welt aber wieder in Ordnung,weil das ORDER BY dann weggekürzt wird.
Select ID,
Bezeichnung, (select top 1 preis from Preise where Preise.ID = Artikel.ID and Preise.Datum <= '1.1.2006' order by Preise.Datum desc ) from Artikel Das würde ich für die schnellste und einfachste Lösung halten. |
Re: Artikelpreis zu gegenem Datum
Ah, Alzaimar hat mein Beispiel konkretisiert. Und ich habe mal in der richtigen Datenbank nachgeguckt, wie das geht :
Delphi-Quellcode:
PG steht für Artikel-Preisgruppe (extra Tabelle). Ist der Preis direkt dem Artikel zugeordnet, dann gehts noch kürzer. Der bisher gezeigte Code ist IMHO zu kompliziert / unleserlich für den Zweck.
CREATE PROCEDURE ERRECHNEPREIS (
ID_ART INTEGER, PGNR SMALLINT, ABDATUM DATE) RETURNS ( PREIS DECIMAL(15,2)) AS BEGIN SELECT FIRST 1 PREIS FROM ARTPG WHERE (PGNR=:PGNR) AND (ABDATUM <= :ABDATUM) ORDER BY ABDATUM DESC INTO :PREIS; IF (PREIS IS NULL) THEN PREIS = 0; SUSPEND; END^ |
Re: Artikelpreis zu gegenem Datum
@Hansa: Deine Procedure liefert mir aber nur den Preis eines Artikels. Ich brauche aber eine Liste (Resultsut) von allen Artikeln und dem zugehörigem Preis zu gegebenem Datum.
Aber meine Lösung klappt ja mittlerweilen, warum noch lange rumexperimentieren. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz