Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQL - Nach nicht direkt gegebenem Datum suchen (https://www.delphipraxis.net/188786-sql-nach-nicht-direkt-gegebenem-datum-suchen.html)

e-gon 7. Apr 2016 07:44

Datenbank: MS Access • Version: 2007 • Zugriff über: TADOQuery

SQL - Nach nicht direkt gegebenem Datum suchen
 
Hallo,

ich habe da ein SQL-Problem mit MS Access:
Relationale Datenbank mit zwei Tabellen. Tabelle 1 enthält Artikel, Tabelle 2 Preise, die ab einem bestimmten Datum galten.

Beispiel für Tabelle 2:
ArtikelID Datum Preis
1 01.01.2016 3,29
1 24.01.2016 3.19
1 11.02.2016 3,31
1 03.03.2016 3,35
1 01.04.2016 3,39

Will ich jetzt wissen, wie hoch der Preis für den Artikel mit der ArtikelID 1 am 26.02.2016 war, kann ich das ja mit Hilfe des "Top"-Befehls (unter mySQL "Limit"-Befehl) einfach lösen:
Code:
SELECT Top 1 PREISE.Preis FROM PREISE WHERE PREISE.ArtikelID=1 AND PREISE.Datum<=#02/26/2016# ORDER BY PREISE.Datum DESC;
Brauche ich allerdings eine Liste aller Artikel, hilft mir der Top-Befehl nicht weiter, da mir immer nur der erste Artikel angezeigt wird:
Code:
SELECT Top 1 PREISE.Preis FROM PREISE WHERE PREISE.Datum<=#02/26/2016# ORDER BY PREISE.Datum DESC;
Wie kann ich solch eine Liste erstellen oder unter welchem Stichwort finde ich passende Antworten?

Gruß
e-gon

PS: Wie bekommt man denn die Spalten in eine Tabelle?

Neutral General 7. Apr 2016 07:54

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Im ersten Moment fällt mir das hier ein:

Code:
SELECT
  artikel.ID,
  (SELECT Top 1 PREISE.Preis FROM PREISE WHERE PREISE.ArtikelID=artikel.ID AND PREISE.Datum<=#02/26/2016# ORDER BY PREISE.Datum DESC) as preis
FROM artikel

baumina 7. Apr 2016 07:54

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Select auf Artikel-Tabelle, in der Feldliste eine Subquery mit Top auf die Preistabelle.

So in etwa:
SQL-Code:
select art.*, (select Preis from Preise where ArtikelID=art.ArtikelID and ....) Preis
from Artikel art
where ...

e-gon 7. Apr 2016 15:37

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Hallo,

erstmal danke für die Antworten. Wie es aussieht ist es doch kein Problem von der Stange.

Der zeitliche Aufwand ist natürlich bei solch eine Mehrfachabfrage recht groß. Ich muss mal ausprobieren, ob das noch akzeptabel ist.

Aber schon Mal danke für die Hilfe!

Gruß
e-gon

nahpets 7. Apr 2016 16:06

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Keine Ahnung, ob Access das kann, aber meinst Du sowas?
Delphi-Quellcode:
select *
from Preise a, Artikel c
where a.ArtikelID = c.ArtikelID
and  c.Datum = b.Datum
and  exists
(
  select b.ArtikelID, max(b.Datum) as Datum
  from Preis b
  where b.datum <= #02/26/2016#
  and  b.ArtikelID = a.ArtikelID
  group by b.ArtikelID
)
order by a.datum desc
Bei genauerer Überlegung wird es das wohl eher nicht sein.

Meiner Meinung nach solltest Du als erstes der Tabelle 2 auch einen eindeutigen Schlüssel "verpassen", damit ein Datensatz über diesen auch eindeutig angesprochen werden kann.

Neutral General 7. Apr 2016 16:48

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Zitat:

Zitat von e-gon (Beitrag 1334913)
Hallo,
erstmal danke für die Antworten. Wie es aussieht ist es doch kein Problem von der Stange.
Der zeitliche Aufwand ist natürlich bei solch eine Mehrfachabfrage recht groß. Ich muss mal ausprobieren, ob das noch akzeptabel ist.

Wie viele Datensätze erwartest du denn?
Weiß jetzt nicht wie langsam/schnell Access ist aber ich hatte auch schon SQLs mit mehreren (5+) Subselects und wenn die Datenmengen nicht riesig waren und die Indices ordentlich gesetzt waren lief auch das schnell genug.

jobo 7. Apr 2016 19:14

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Versuch mal:
Code:

select a.*
  from table2 a
  join (select ArtikelID, max(Datum) xdate
          from table2 ap
         where ap.Datum < '26.02.2016'
         group by ArtikelID) x
    on a.ArtikelID = x.ArtikelID
   and a.Datum = x.xdate
-- oder  

select a.*
  from table2 a,
       (select ArtikelID, max(Datum) xdate
          from table2 ap
         where ap.Datum < '26.02.2016'
         group by ArtikelID) x
 where a.ArtikelID = x.ArtikelID
   and a.Datum = x.xdate
Gibt wahrscheinlich 1 oder max 2 Fullscans, mehr sollten es nicht werden. Bei der Syntax weiß ich nicht, was Access da eher schluckt.

p80286 7. Apr 2016 22:05

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Ein klein wenig anders:
SQL-Code:
select a.Artikel, xpreis, xdate
from a join
(select id
       ,preis as xpreis
       ,max (datum) xdate
 from tab2
 where date<=grenzdatum  -- hier das Datum einsetzen
 Group by id) x on (x.id=a.id)
Gruß
K-H

jobo 7. Apr 2016 22:25

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Ok, das Gleichheitszeichen meinetwegen. Aber bei dem Rest bleibe ich bei meiner Version.
Ich habe es so verstanden, dass für alle Artikel (in der Tabelle ist ein Artikel mehrfach enthalten) jeweils der ausgegeben werden soll, der am gewählten Tag gültig ist, also n aus m Datensätzen selektiert werden müssen.

joachimd 8. Apr 2016 10:15

AW: SQL - Nach nicht direkt gegebenem Datum suchen
 
Wenn Du eine nach Datum aufsteigende eindeutige ID hättest, wäre es Standard ;)
Du willst zunächst wissen, welche Datensätze in Frage kommen:
Code:
  select artikelid, max(datum) as datum
    from #preise
    where datum<='2010-01-01' -- your date here
    group by artikelid
Das Ergebnis wird in einem INNER JOIN mit der Ursprungs-Tabelle verknüpft
Code:
select p.* from #preise p
inner join
(
  select artikelid, max(datum) as datum
    from #preise
    where datum<='2010-01-01' -- your date here
    group by artikelid
) pl
on (p.artikelid=pl.artikelid) and (p.datum=pl.datum)
Hinweis: Dies ist in Advantage Database getestet - da es aber SQL Standard ist, sollte es sogar ACCESS können.
#preise ist eine temp-Tabelle zum Testen, wie folgt erzeugt:
Code:
create table #preise(
id autoinc,
artikelid integer,
datum date,
preis money
);
insert into #preise(artikelid,datum,preis) values(1,'2012-01-01',12);
insert into #preise(artikelid,datum,preis) values(1,'2011-01-01',11);
insert into #preise(artikelid,datum,preis) values(1,'2010-01-01',10);
insert into #preise(artikelid,datum,preis) values(1,'2009-01-01',9);

insert into #preise(artikelid,datum,preis) values(2,'2012-01-01',24);
insert into #preise(artikelid,datum,preis) values(2,'2011-01-01',23);
insert into #preise(artikelid,datum,preis) values(2,'2010-01-01',22);
insert into #preise(artikelid,datum,preis) values(2,'2009-01-01',21);


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz