Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   ADOQuery berechnetes Feld (https://www.delphipraxis.net/200870-adoquery-berechnetes-feld.html)

jobo 6. Jun 2019 12:48

AW: ADOQuery berechnetes Feld
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1434039)
Eventuell geht auch dashier, ist kürzer und dürfte resourcen- / laufzeitschonender sein: ..

Ja, also ein Union aus MengeMitIsNotNull und MengeMitIsNull wäre wahrscheinliche einfach: Menge.
Ich fürchte ja wie oben geschrieben, dass outer verkehrt rum läuft. Dazu könnte Luckner einfach mal eine SQL Stichprobe ohne das ganze Drumrum machen.

Delphi.Narium 6. Jun 2019 13:01

AW: ADOQuery berechnetes Feld
 
Nö, nicht ganz.

Laut der letzten Frage
Zitat:

Wenn Material aufgebraucht ist, merke ich, wenn alle (Materialrollen.DatumAb <> NULL)ist. Also alle Materialrollen ein Abgangsdatum haben. Andererseits könnte es auch funktionieren, wenn man herausfindet, dass wenn das Produkt aus der Multiplikation = 0 ist. Irgendwas in dieser Richtung.
fehlen ja die Sachen, bei denen Materialrollen.DatumAb <> NULL (lieber Materialrollen.DatumAb is not NULL) ist.

Da in der ursprünglichen Abfrage aber auf Materialrollen.DatumAb IS NULL abgefragt wurde, kann die vermisste Menge ja garnicht im Ergebnis sein.

Meine Idee war halt zuerst: Nehmen wird die Abfrage mit dem bisherigen, gewünschten und inzwischen korrekten Teilergebnis und fügen noch mal das "Gegenstück" für den fehlenden Rest hinzu.

Geht am Einfachsten erstmal mit Union All.

Soweit, so naiv.

Die Einschränkung, die für den "Datenverlust" verantworlich zeichnet, einfach rauszunehmen, war dann ein Gedanke, der erst "Minuten später" (der Groschen fällt halt pfennigweise) kam.

Lassen wir dem TE jetzt erstmal ein bisserl Zeit zum verdauen. Danach wird er uns (hoffentlich) über den Erfolg / Misserfolg unterrichten ;-)

Luckner 6. Jun 2019 15:27

AW: ADOQuery berechnetes Feld
 
Hallo Delphi.Narium,
habe beide Versionen ausprobiert. Die 2. Select-Anweisung liefert ersmal einen unbekannten Fehler. Werde versuchen ihn, mit meinen Kenntnissen, zu korrigieren.
Die 1.-te, längere Anweisung liefert folgendes:

Material-Nr: / Bezeichnung / Bestand / aufgebraucht
265627 / schreib-weiß, permanent / 1300465,5 / ja
265627 / schreib-weiß, permanent / 5148 / nein


usw. für alle anderen Materialrollen.

Es sollten nur die Datensätze bleiben die ein "nein" enthalten und nur die, die ein "ja" enthalten, dann aber der Bestand = 0.

UNION ALL
SELECT
Materialrollen.[Mat-Nr], !!!! habe ich korrigiert.
Materialrollen.[Mat-Nr],

Gruß, Luckner

Delphi.Narium 6. Jun 2019 15:49

AW: ADOQuery berechnetes Feld
 
Das 2. SQL hab' ich oben überarbeitet.

Zitat:

Es sollten nur die Datensätze bleiben die ein "nein" enthalten und nur die, die ein "ja" enthalten, dann aber der Bestand = 0.
SQL-Code:
select * from (
  SELECT
    MaterialNr,
    sum((Arbeitsbreite / 1000) * lfm) as BESTAND,
    Bezeichnung,
    Aufgebraucht
  from (
    SELECT
      Materialrollen.[Mat-Nr] As MaterialNr,
      Materialrollen.[Arb-Breite] As Arbeitsbreite,
      Materialrollen.lfm,
      [Material-Stamm].Bezeichnung,
      'nein' as Aufgebraucht
    FROM Materialrollen
    LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr]
    WHERE (
               ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ')
           AND ([Material-Stamm].aktuell= -1)
           AND (Materialrollen.DatumAb is NULL)
           AND (Materialrollen.[Arb-Breite] > 179)
          )
    UNION ALL
    SELECT
      Materialrollen.[Mat-Nr],
      Materialrollen.[Arb-Breite],
      Materialrollen.lfm,
      [Material-Stamm].Bezeichnung,
      'ja' as Aufgebraucht
    FROM Materialrollen
    LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr]
    WHERE (
               ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ')
           AND ([Material-Stamm].aktuell= -1)
           AND (Materialrollen.DatumAb is not NULL)
           AND (Materialrollen.[Arb-Breite] > 179)
          )
  )
  group by
    MaterialNr,
    Bezeichnung,
    Aufgebraucht
)
where (Aufgebraucht = 'nein')
or   (Aufgebraucht = 'ja' and Bestand = 0)
Und ja, das muss auch ohne dieses blöde Union all gehen.

Deshalb noch ein Versuch:
SQL-Code:
select * from (
  SELECT
    MaterialNr,
    sum((Arbeitsbreite / 1000) * lfm) as BESTAND,
    Bezeichnung,
    Aufgebraucht
  from (
    SELECT
      Materialrollen.[Mat-Nr] As MaterialNr
      Materialrollen.[Arb-Breite] As Arbeitsbreite,
      Materialrollen.lfm,
      [Material-Stamm].Bezeichnung,
      case Materialrollen.DatumAb when null then 'nein' else 'ja' end as Aufgebraucht
    FROM Materialrollen
    LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr]
    WHERE (
               ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ')
           AND ([Material-Stamm].aktuell= -1)
           AND (Materialrollen.[Arb-Breite] > 179)
          )
  )
  group by
    MaterialNr,
    Bezeichnung,
    Aufgebraucht
)
where (Aufgebraucht = 'nein')
or   (Aufgebraucht = 'ja' and Bestand = 0)
Wenn das jetzt funktioniert, wird's ja schon fast wieder übersichtlich ;-)

Luckner 7. Jun 2019 11:56

AW: ADOQuery berechnetes Feld
 
Hallo Delphi.Narium,

habe beide Versionen ausprobiert. Bei Version 2 (ohne UNION) gibt es gleich einen "unbekannten Fehler". Bei der Version 1 sieht erstmal gut aus. Das Produkt aus der Muliplikation stimmt auch. Aber dann! Habe den entsprechenden Materialrollen, die > 179 sind, ein Materialrollen.DatumAb eingetragen und dann wird dieses Material gar nicht mehr in der Tabelle angezeigt. Eigentlich sollte das Material aufgeführt sein mit Bestand = 0 und Aufgebraucht = ja

Gruß, Luckner

Delphi.Narium 7. Jun 2019 14:58

AW: ADOQuery berechnetes Feld
 
Ich hasse diesen "unbekannten Fehler" aus den Mircosoftprodukten, der ist einfach nie hilfreich bei der Fehlersuche :-( ;-)

Die Klammern stimmten irgendwie nicht, mindestens eine schließende war zuviel und mindestens ein Komma fehlte, also noch ein Versuch:
SQL-Code:
select * from (
  SELECT
    MaterialNr,
    sum(Bestand) as BESTAND,
    Bezeichnung,
    Aufgebraucht
  from (
    SELECT
      Materialrollen.[Mat-Nr] As MaterialNr,
      Materialrollen.[Arb-Breite] / 1000 * Materialrollen.lfm as Bestand,
      [Material-Stamm].Bezeichnung As Bezeichnung,
      case Materialrollen.DatumAb when null then 'nein' else 'ja' end as Aufgebraucht
    FROM Materialrollen
    LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr]
    WHERE [Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + '
    AND  [Material-Stamm].aktuell = -1
    AND  Materialrollen.[Arb-Breite] > 179
  )
  group by
    MaterialNr,
    Bezeichnung,
    Aufgebraucht
)
where (Aufgebraucht = 'nein') or (Aufgebraucht = 'ja' and Bestand = 0)
Zitat:

Aber dann! Habe den entsprechenden Materialrollen, die > 179 sind, ein Materialrollen.DatumAb eingetragen und dann wird dieses Material gar nicht mehr in der Tabelle angezeigt. Eigentlich sollte das Material aufgeführt sein mit Bestand = 0 und Aufgebraucht = ja
Dein Ursprungssql hatte da sowas:
SQL-Code:
AND (Materialrollen.DatumAb is NULL)
. Daraus resultiert:
Zitat:

ein Materialrollen.DatumAb eingetragen und dann wird dieses Material gar nicht mehr in der Tabelle angezeigt
Also entferne die Zeile(n) mit
SQL-Code:
AND (Materialrollen.DatumAb is NULL)
aus dem SQL. Dann sind sie im Ergebnis enthalten, was übrigens dann auch das Union All überflüssig macht.

jobo 7. Jun 2019 15:06

AW: ADOQuery berechnetes Feld
 
Hier ist ein Klammerfehler bei
sum((Bestand

eine reicht.

Luckner 7. Jun 2019 18:46

AW: ADOQuery berechnetes Feld
 
Hallo Delphi.Narium, hallo jobo,

die Aufgabenstellung ist folgende: Ein Lieferant liefert "[Material-Stamm].[Lieferanten-Nr]" verschiedene Papiersorten. Das Material (Papiersorten) liegt bei uns als Rollen von verschiedenen Grössen und Breiten auf Lager.

Aufgabe: Zeige die markierten Materialien "[Material-Stamm].aktuell = -1" des Lieferanten die eine Breite > 179mm haben, die kein Abgangsdatum "Materialrollen.DatumAb" und berechne die Fläche des Materials. Aufgebraucht = nein. Falls Rollen der geforderten Breite vorhanden dann berechne die Fläche. Falls Materialrollen <= 179, dann braucht es keine Summe (kann aber trotzdem berechnet und angezeigt werden) aber der Hinweis "aufgebraucht = ja" angezeigt werden. Falls keine Rollen vorhanden, dann Fläche = 0 und aufgebraucht = ja.

Ich hoffe, ich konnte das Problem jetzt besser beschreiben als meine Select-Anweisungen.

Gruß, Luckner

Delphi.Narium 7. Jun 2019 21:06

AW: ADOQuery berechnetes Feld
 
Zitat:

die Aufgabenstellung ist folgende:
Ein Lieferant liefert "[Material-Stamm].[Lieferanten-Nr]" verschiedene Papiersorten.
SQL-Code:
select * from [Material-Stamm] where [Lieferanten-Nr] = :LieferantenNr
Zitat:

Das Material (Papiersorten) liegt bei uns als Rollen von verschiedenen Grössen und Breiten auf Lager.

Aufgabe:

Zeige die markierten Materialien "[Material-Stamm].aktuell = -1"
SQL-Code:
select * from [Material-Stamm]
where aktuell = -1
and  [Lieferanten-Nr] = :LieferantenNr
Zitat:

des Lieferanten die eine Breite > 179mm haben,
SQL-Code:
select * from [Material-Stamm]
where aktuell = -1
and  Lieferanten-Nr] = :LieferantenNr
and  Breite > 179
Zitat:

die kein Abgangsdatum "Materialrollen.DatumAb"
SQL-Code:
select *
from [Material-Stamm] s
inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite > 179
and  r.DatumAb is null
Zitat:

und berechne die Fläche des Materials.
SQL-Code:
select
  r.[Mat-Nr] As MaterialNr,
  r.[Arb-Breite] / 1000 * r.lfm as Bestand,
  s.Bezeichnung As Bezeichnung
from [Material-Stamm] s
inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite > 179
and  r.DatumAb is null
Zitat:

Aufgebraucht = nein.
SQL-Code:
select
  r.[Mat-Nr] As MaterialNr,
  r.[Arb-Breite] / 1000 * r.lfm as Bestand,
  s.Bezeichnung As Bezeichnung,
  'nein' as Aufgebraucht
from [Material-Stamm] s
inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite > 179
and  r.DatumAb is null
Zitat:

Falls Materialrollen <= 179, dann braucht es keine Summe
(kann aber trotzdem berechnet und angezeigt werden)
aber der Hinweis "aufgebraucht = ja" angezeigt werden.
SQL-Code:
select
  r.[Mat-Nr] As MaterialNr,
  0 as Bestand,
  s.Bezeichnung As Bezeichnung,
  'ja' as Aufgebraucht
from [Material-Stamm] s
inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite <= 179
and  r.DatumAb is null
Zitat:

Falls keine Rollen vorhanden, dann Fläche = 0 und aufgebraucht = ja.
SQL-Code:
select
  r.[Mat-Nr] As MaterialNr,
  case
    when r.[Arb-Breite] is null
  then
    0
  else
    r.[Arb-Breite] / 1000 * r.lfm
  end as Bestand,
  s.Bezeichnung As Bezeichnung,
  case when r.[Arb-Breite] is null then 'ja' else 'nein' as Aufgebraucht
from [Material-Stamm] s
left join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite <= 179
and  r.DatumAb is null
Zitat:

Ich hoffe, ich konnte das Problem jetzt besser beschreiben als meine Select-Anweisungen.
Ehrlich gesagt: nicht wirklich, da ist irgendwas noch widersprüchlich (oder es ist zu spät) :-(

Eventuell in die Richtung?
SQL-Code:
select
  r.[Mat-Nr] As MaterialNr,
  r.[Arb-Breite] / 1000 * r.lfm as Bestand,
  s.Bezeichnung As Bezeichnung,
  'nein' as Aufgebraucht
from [Material-Stamm] s
inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite > 179
and  r.DatumAb is null
union all
select
  r.[Mat-Nr] As MaterialNr,
  case
    when r.[Arb-Breite] is null
  then
    0
  else
    r.[Arb-Breite] / 1000 * r.lfm
  end as Bestand,
  s.Bezeichnung As Bezeichnung,
  case when r.[Arb-Breite] is null then 'ja' else 'nein' as Aufgebraucht
from [Material-Stamm] s
left join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
where s.[Lieferanten-Nr] = :LieferantenNr
and  s.aktuell = -1
and  s.Breite <= 179
and  r.DatumAb is null
Nun noch mit dem Versuch der Summierung:
SQL-Code:
select
  MaterialNr,
  Sum(Bestand) as Bestand,
  Bezeichnung,
  Aufgebraucht
from
(
  select
    r.[Mat-Nr] As MaterialNr,
    r.[Arb-Breite] / 1000 * r.lfm as Bestand,
    s.Bezeichnung As Bezeichnung,
    'nein' as Aufgebraucht
  from [Material-Stamm] s
  inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
  where s.[Lieferanten-Nr] = :LieferantenNr
  and  s.aktuell = -1
  and  s.Breite > 179
  and  r.DatumAb is null
  union all
  select
    r.[Mat-Nr] As MaterialNr,
    case
      when r.[Arb-Breite] is null
    then
      0
    else
      r.[Arb-Breite] / 1000 * r.lfm
    end as Bestand,
    s.Bezeichnung As Bezeichnung,
    case when r.[Arb-Breite] is null then 'ja' else 'nein' as Aufgebraucht
  from [Material-Stamm] s
  left join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr]
  where s.[Lieferanten-Nr] = :LieferantenNr
  and  s.aktuell = -1
  and  s.Breite <= 179
  and  r.DatumAb is null
)
group by
  MaterialNr,
  Bezeichnung,
  Aufgebraucht
Inzwischen hab' ich den Durchblick verloren, keine Ahnung wieviele Denk- und Syntaxfehler ich da eingebaut habe, aber vielleicht ist es ja nicht ganz hoffnungslos ;-)

jobo 9. Jun 2019 09:25

AW: ADOQuery berechnetes Feld
 
Den Aufwand von DN in Ehren, aber es ist doch ein mühsames Geschäft. Denn es fehlt hier Tabellenstruktur (Create Statement mit Constraints) und weil diese oft nicht genau genug sind, echte Testdaten.
Also mein Vorschlag:
Luckner postet Table Create Scripte und Daten (handvoll insert Statements) der betroffenen Daten. Das ergibt für alle Beteiligten (Helfer und TE) ein 100% nachvollziehbares Beispiel und erspart diese Stille Post Nummer. Jeder der es später nachvollziehen will, kann es dann auch wirklich, so wie es im Forum gedacht ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:54 Uhr.
Seite 3 von 4     123 4      

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