Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Ersatz für DISTINCT ?? (https://www.delphipraxis.net/74472-ersatz-fuer-distinct.html)

TBx 3. Aug 2006 23:11

Re: Ersatz für DISTINCT ??
 
Hallo Hansa,

versuch mal folgendes:

SQL-Code:
CREATE PROCEDURE ERMITTLE_ALLEMWSTSP (ABDATUM DATE)
RETURNS ( 
    ID_OUT INTEGER,
    MWSTSATZ_OUT INTEGER,
    ABDATUM_OUT DATE,
    MWSTWERT_OUT DECIMAL(15,2))
AS
begin
  FOR SELECT MWSTSATZ
        FROM MWST
        WHERE ABDATUM <= :ABDATUM
        GROUP BY MWSTSATZ /* GROUP BY statt SELECT DISTINCT verwendet, da GROUP BY indiziert arbeitet, DISTINCT nicht */
        INTO :MWSTSATZ_OUT
  DO /* fuer jeden bis :ABDATUM vorhandenen MWSTSATZ */
  BEGIN
    /* juengstes Aenderungsdatum ermitteln */
    SELECT max (ABDATUM)
      FROM MWST
      WHERE MWSTSATZ = :MWSTSATZ_OUT
        AND ABDATUM <= :ABDATUM
      INTO :ABDATUM_OUT;
    /* jetzt noch ID und Wert ermitteln */
    SELECT ID, MWSTWERT
      FROM MWST
      WHERE MWSTSATZ = :MWSTSATZ_OUT
        AND ABDATUM = :ABDATUM_OUT
      INTO :ID_OUT, :MWSTWERT_OUT;
    SUSPEND;
  END
end
Du solltest aus Geschwindigkeitsgründen in der Tabelle MWST Indexe auf
  • MWSTSATZ
  • MWSTWERT
  • ABDATUM
eingerichtet haben.

Des weiteren bin ich davon ausgegangen, dass es einen Unique über MWSTSATZ und ABDATUM gibt.
Ansonsten könnte die letzte select in der Procedure ein
multiple rows in a singelton select
hervorrufen.

Das Ganze ist runtergetippt und nicht getestet, da ich gerade keinen DB-Server am Laufen habe.
Bei Fehlfunktion bitte nachfragen.

Hope it helps

onlinekater

Mavarik 4. Aug 2006 07:35

Re: Ersatz für DISTINCT ??
 
Warum so eine kleinigkeit auf den SQL Server auslagern?

Wie wäre es mit?
Delphi-Quellcode:
function GetMwStWert(D:Datumstyp):real; // Noch aus früheren Zeiten... Da gabe es noch keine Datetime!
var
  DDD : Datumstyp;
begin
 if D.Jahr > 92
   then begin
          ValDate('01.04.98',DDD);
          if AbsDatum(D) >= AbsDatum(DDD)
            then result := 16.0
            else result := 15.0;
        end
   else result := 14.0;
end;
Frank :coder:

PS.: Die Erweiterung für 01.01.07 ist ja ein Kinderspiel!

marabu 4. Aug 2006 08:13

Re: Ersatz für DISTINCT ??
 
Hallo Frank,

Zitat:

Zitat von Mavarik
Warum so eine kleinigkeit auf den SQL Server auslagern?

Hansa hat sich nunmal für ein RDBMS entschieden. Er speichert bei einer Artikelposition einen USt-Schlüssel (1 für ermäßigter USt-Satz), welcher innerhalb der Datenbank aufgelöst werden muss. Deshalb gibt es eine Tabelle mit den Umsatzsteuersätzen. Und weil diese Sätze per Gesetz fortgeschrieben werden ist die Tabelle als history table ausgelegt. Bei einer Auslagerung der Steuersatzermittlung in dein Programm wären die Daten in der Datenbank nicht mehr "abgeschlossen". Eine Auswertung mit einem SQL Report-Tool wäre nicht mehr möglich, weil das Wissen um die Bedeutung der Steuersätze außerhalb der Datenbank (in deinem Programm) vorgehalten wird. Das ist unbedingt zu vermeiden.

Freundliche Grüße vom marabu

Mavarik 4. Aug 2006 08:23

Re: Ersatz für DISTINCT ??
 
Zitat:

Zitat von marabu
Bei einer Auslagerung der Steuersatzermittlung in dein Programm wären die Daten in der Datenbank nicht mehr "abgeschlossen". Eine Auswertung mit einem SQL Report-Tool wäre nicht mehr möglich, weil das Wissen um die Bedeutung der Steuersätze außerhalb der Datenbank (in deinem Programm) vorgehalten wird. Das ist unbedingt zu vermeiden.

Ahh alles klar, habe ich nicht "drüber" nachgedacht....

Das leuchtet mit ein, danke für die Erläuterung!

Frank :coder:

MarkusB 4. Aug 2006 08:41

Re: Ersatz für DISTINCT ??
 
Moin!

SQL-Code:
select max(MWSTWERT_OUT) from
(select MWSTWERT_OUT from Tabelle
where ABDATUM_OUT <= Datum)
Hilft das?

Viele Grüße
Markus
:gruebel:

dataspider 4. Aug 2006 10:07

Re: Ersatz für DISTINCT ??
 
Hi Hansa,

was gefällt dir an meiner Procedure nicht. Sie liefert genau das, was du willst.
Und onlinekater ist ja genau zum gleichen Ergebnis gekommen.

Cu, Frank

TBx 4. Aug 2006 10:32

Re: Ersatz für DISTINCT ??
 
Zitat:

Zitat von Hansa
Unter der Voraussetzung, daß es mind. 3 Sätze gibt, geht es so :

SQL-Code:
CREATE PROCEDURE ERMITTLE_ALLEMWSTSP (
    ABDATUM DATE)
RETURNS (
    MWSTSATZ_OUT INTEGER,
    MWSTWERT_OUT DECIMAL(15,2))
AS
begin
FOR
SELECT FIRST 3 MWSTSATZ, MWSTWERT FROM MWST WHERE ABDATUM <= :ABDATUM ORDER BY MWSTSATZ,ABDATUM DESC
  INTO :MWSTSATZ_OUT,:MWSTWERT_OUT
  DO
  SUSPEND;
end^
Problem scheint also tatsächlich auf den Kern reduziert. Oder sieht jemand noch einen Fehler ?

Hallo Hansa!
Nein, das funktioniert nicht korrekt.
Wenn Du z. B. folgende Daten hast:

Zitat:

ID, MWSTSATZ, ABDATUM, MWSTWERT
1, 0, 01.01.1980, 0
2, 0, 31.12.1980, 63
3, 1, 29.05.1990, 13
4, 2, 26.09.1995, 16
5, 2, 01.01.1980, 14
6, 1, 01.01.1980, 7
und Du rufst obige Procedure mit ABDATUM = '01.01.2005' auf, dann erhieltest Du folgendes:

Zitat:

ID_OUT, MWSTSATZ_OUT, ABDATUM_OUT, MWSTWERT_OUT
1, 0, 01.01.1980, 0
2, 0, 31.12.1980, 63
6, 1, 01.01.1980, 7
Ich denke, das wäre nicht in Deinem Sinne.

Mir ist gerade erst aufgefallen, das ich fast dieselbe Procedure gepostet habe, wie Frank. Da habe ich nicht so ganz aufgepaßt. Meine Zusatzbemerkungen passen zu seiner Procedure genauso wie zu meiner.

Gruß

Thomas

alex517 4. Aug 2006 10:48

Re: Ersatz für DISTINCT ??
 
Hi Hansa,

wie wäre es denn damit:
SQL-Code:
CREATE PROCEDURE ERMITTLE_ALLEMWSTSP (
    ABDATUM DATE)
RETURNS (
    ID_OUT INTEGER,
    MWSTSATZ_OUT INTEGER,
    ABDATUM_OUT DATE,
    MWSTWERT_OUT DECIMAL(15,2))
AS
BEGIN
  if (ABDATUM is NULL) then ABDATUM = CURRENT_DATE;
  for
    select
      distinct S.MWSTSATZ
    from
      mwst S
    into
      :MWSTSATZ_OUT
    DO BEGIN
      for
        select first 1
          M.ID,
          M.ABDATUM,
          M.MWSTWERT
        from
          mwst M
        where
          M.MWSTSATZ = :MWSTSATZ_OUT and
          M.ABDATUM <= :ABDATUM
        order by
          M.ABDATUM desc
        INTO
          :ID_OUT,
          :ABDATUM_OUT,
          :MWSTWERT_OUT
        DO
          SUSPEND;
    END
END
alex

Niko 4. Aug 2006 13:01

Re: Ersatz für DISTINCT ??
 
Hi,

es geht auch mit "reinem" SQL:
SQL-Code:
select m1.MWSTSATZ, m1.MWSTWERT
from MWST m1 join MWST m2 using (MWSTSATZ)
where m2.ABDATUM_OUT <= :ABDATUM
group by m1.MWSTSATZ, m1.ABDATUM, m1.MWSTWERT
having m1.ABDATUM = max(m2.ABDATUM)
order by m1.MWSTSATZ
into :MWSTSATZ_OUT, :MWSTWERT_OUT
Ungetestet, sollte aber passen. Ob das jetzt besonders performant ist kann ich nicht sagen. Das dürfte bei der kleinen Tabelle aber sowieso nichts ausmachen.

alex517 4. Aug 2006 13:15

Re: Ersatz für DISTINCT ??
 
Hi Niko

Zitat:

Zitat von Niko
es geht auch mit "reinem" SQL:

Überredet...
..wenn man "using (MWSTSATZ)" durch
SQL-Code:
on (m2.MWSTSATZ = m1.MWSTSATZ)
ersetzt.

alex


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:55 Uhr.
Seite 2 von 3     12 3      

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