Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   MySQL versus MsSQL Syntax Group By (https://www.delphipraxis.net/207879-mysql-versus-mssql-syntax-group.html)

Ykcim 11. Mai 2021 17:17

Datenbank: MsSQL • Version: 8 • Zugriff über: FireDac

MySQL versus MsSQL Syntax Group By
 
Hallo Zusammen,

ich arbeite seit 15 Jahren immer nur mit MySQL-Datenbanken und muss jetzt ein Projekt auf MsSQL umsetzen. Das klappte bis jetzt sehr gut, aber ich stolper gerade über die Group BY Anweisung...
Delphi-Quellcode:
SELECT    a.zynrefkl AS 'Nr. beim Kunden',
         a.afg_oms1 AS 'Artikel-Bezeichnung',
         b.in__vrrd AS 'Bestand',
         a.per__chk AS 'Abgreifmenge',
         a.minstock AS 'Mindestbestand',
         CASE WHEN b.in__vrrd<a.minstock then 'Mindestmenge unterschritten' ELSE '' END AS 'Kommentar',
         SUM(c.b_aantal) AS 'Rückstand'
FROM afgart__ a
LEFT JOIN afgant__ b ON b.afg__ref = a.afg__ref
LEFT JOIN bstlyn__ c ON c.afg__ref = a.afg__ref AND c.vrzvouur<GETDATE() AND c.vrz__tst = '1'
WHERE a.kla__rpn = 'LBBW'
GROUP BY a.zynrefkl
Ich habe dieses SQL-Statement und bekomme die Fehlermeldung:
Zitat:

Column ’afgart__.afg_oms1’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Ich habe leider keine für mich nachvollziehbare Lösung gefunden. Kann mir jemand dabei helfen?

Vielen Dank
Patrick

mkinzler 11. Mai 2021 17:35

AW: MySQL versus MsSQL Syntax Group By
 
Es muss jede Spalte in der Feldliste entweder als Aggegat oder als Teil der Gruppierung vorliegen.
Bei Dir ist das eigentlich für keine der Spalten der Fall. Mich wundert, dass es bei MySQL funktioniert.

Ykcim 11. Mai 2021 18:09

AW: MySQL versus MsSQL Syntax Group By
 
Ich habe gerade Schwierigkeiten, die Logik zu verstehen.

a.zynrefkl ist eine ArtikelNr. Ich möchte das Ergebnis der Summierung für jede ArtikelNr bekommen.
a.afg_oms1 das ist die Artikelbeschreibung. Die gibt es nur einmal. Ich verstehe nicht, was ich hier berechnen soll. Ich kann sie natürlich in die Group By Klausel hinzufügen, aber das hätte keinen Sinn, oder?
b.in__vrrd kommt einmal vor und hängt an der ArtikelNr.
a.per__chk ist die VE und wir aus der Zeile der gruppierten ArtikelNr genommen
a.minstock gilt das gleiche

Ich verstehe leider nicht, warum ich künstlich irgendetwas berechnen soll - eventuell damit ungewollte Effekte erziele - nur um etwas zu gruppieren. Ich wüsste nicht, wie ich das in meinem Fall machen sollte...

Ich habe es jetzt mal so versucht, muss aber das Erbegnis mühselig kontrollieren...

Delphi-Quellcode:
SELECT    a.zynrefkl AS 'Nr. beim Kunden',
         a.afg_oms1 AS 'Artikel-Bezeichnung',
         b.in__vrrd AS 'Bestand',
         a.per__chk AS 'Abgreifmenge',
         a.minstock AS 'Mindestbestand',
         CASE WHEN b.in__vrrd<a.minstock then 'Mindestmenge unterschritten' ELSE '' END AS 'Kommentar',
         SUM(c.b_aantal) AS 'Rückstand',
         SUM(d.aant_uit) AS 'Gesamtverbrauch'
FROM afgart__ a
LEFT JOIN afgant__ b ON b.afg__ref = a.afg__ref
LEFT JOIN bstlyn__ c ON c.afg__ref = a.afg__ref AND c.vrzvouur<GETDATE() AND c.vrz__tst = '1'
LEFT JOIN hisafg__ d ON d.afg__ref = a.afg__ref AND MONTH(d.datum___) = MONTH(GETDATE())
WHERE a.kla__rpn = 'LBBW'
GROUP BY a.zynrefkl, a.afg_oms1, b.in__vrrd, a.per__chk, a.minstock

mkinzler 11. Mai 2021 18:16

AW: MySQL versus MsSQL Syntax Group By
 
Gruppieren heisst ja Zusammenfassen. Die Felder vo a kann man alle in die Gruppierung nehmen.
Wieviel Werte erzeugen die Joins jeweils?

Ykcim 11. Mai 2021 18:25

AW: MySQL versus MsSQL Syntax Group By
 
b (afgant__ ) hat eine 1:1 Verbindung
C (bstlyn__) und d (hisafg__) geben mehrere Daten aus. Aber durch die Summierung werden daraus auch nur ein Datensatz...

Ich muss mich an diese Denkweise gewöhnen. Eigentlich packe ich immer so wenig wie möglich in die Gruppierung, weil ich mir einbilde, dass die Performance dann besser ist...

mkinzler 12. Mai 2021 07:59

AW: MySQL versus MsSQL Syntax Group By
 
Eine andere Alternative wäre es Aggegate zu erzwingen und so aus einem einzelnen Wert ein Aggegat zu machen, das kostet aber sicherlich mehr als eine erweiterte Gruppierung.

Delphi.Narium 12. Mai 2021 11:48

AW: MySQL versus MsSQL Syntax Group By
 
In "normalem" SQL wäre das wohl so erforderlich:
SQL-Code:
SELECT   a.zynrefkl AS 'Nr. beim Kunden',
         a.afg_oms1 AS 'Artikel-Bezeichnung',
         b.in__vrrd AS 'Bestand',
         a.per__chk AS 'Abgreifmenge',
         a.minstock AS 'Mindestbestand',
         CASE WHEN b.in__vrrd < a.minstock then 'Mindestmenge unterschritten' ELSE '' END AS 'Kommentar',
         SUM(c.b_aantal) AS 'Rückstand'
FROM afgart__ a
LEFT JOIN afgant__ b ON b.afg__ref = a.afg__ref
LEFT JOIN bstlyn__ c ON c.afg__ref = a.afg__ref AND c.vrzvouur<GETDATE() AND c.vrz__tst = '1'
WHERE a.kla__rpn = 'LBBW'
GROUP BY
  a.zynrefkl,
  a.afg_oms1,
  b.in__vrrd,
  a.per__chk,
  a.minstock,
  'Kommentar' -- da weiß ich jetzt garnicht, ob MS-SQL das so kann
Ins Group by muss schlicht und einfach alles, was nicht per Sum, Min, Max, ... zusammengefasst wird.

Rolf Frei 12. Mai 2021 13:58

AW: MySQL versus MsSQL Syntax Group By
 
Könnte MS SQL nicht auch die Feldlistennummer verwenden, also "GROUP BY 1,2,3,4,5,6"? Ansonsten müsste er glaube ich auch die Resultfeldnamen verwenden, also nicht die zu grundeligenden DB-Feldnamen, also die deutschen AS Namen aus dem SQL.

Delphi.Narium 12. Mai 2021 14:06

AW: MySQL versus MsSQL Syntax Group By
 
Eher nicht, das ist, soweit ich weiß, eine MySQL-Spezialität.

Ebenso wie die unvollständige Group By Liste, die nicht alle nichtaggregierten Spalten enthalten muss.

Ykcim 12. Mai 2021 16:59

AW: MySQL versus MsSQL Syntax Group By
 
Aktuell verzweifle ich gerade. Eigentlich eine Sache von ein paar Minuten und sitze jetzt schon Stunden da dran...

Delphi-Quellcode:
SELECT    a.zynrefkl AS 'Artikelnummer',
         a.afg_oms1 AS 'Artikelbezeichnung 1',
         b.in__vrrd AS 'Bestand',
         a.per__chk AS 'Abgreifmenge',
         a.minstock AS 'Mindestbestand',
         CASE WHEN b.in__vrrd<a.minstock then 'Mindestmenge unterschritten' ELSE '' END AS 'Bestandskommentar',
         '' AS Kommentar,
         COALESCE(SUM(c.b_aantal),0) AS 'Rückstand',
         COALESCE(SUM(d.aant_uit), 0) AS 'Gesamtverbrauch'
FROM afgart__ a
LEFT JOIN afgant__ b ON b.afg__ref = a.afg__ref
LEFT JOIN bstlyn__ c ON c.afg__ref = a.afg__ref AND c.vrzvouur<GETDATE() AND c.vrz__tst = '1'
LEFT JOIN hisafg__ d ON d.afg__ref = a.afg__ref AND MONTH(d.datum___) = MONTH(GETDATE())
WHERE a.kla__rpn = 'LBBW'
AND    a.zynrefkl <> ''
GROUP BY   a.zynrefkl,
         a.afg_oms1,
         b.in__vrrd,
         a.per__chk,
         a.minstock
Das oben gepostete SQL-Statement funktioniert jetzt, wenn ich es mit HeidSQL ausführe. Ich bekomme 229 Datensätze angezeigt.

Wenn ich das Statement jetzt aber über meine Software absetze, bekomme ich nur 50 Datensätze raus...

Delphi-Quellcode:
procedure TDB_Modul.Get_WeeklyStock(AStream: TStream);
var     Logic: TLogic;
      Query: TFDQuery;
begin
   Logic := TLogic.create;
   Logic.Set_Query(Query, MSConnect);
   Try
      Query.SQL.Add('SELECT  a.zynrefkl AS ' + QuotedStr('Artikelnummer') + ', '+
                             'a.afg_oms1 AS ' + QuotedStr('Artikelbezeichnung 1') + ', '+
                             'b.in__vrrd AS ' + QuotedStr('Bestand') + ', '+
                             'a.per__chk AS ' + QuotedStr('Abgreifmenge') + ', '+
                             'a.minstock AS ' + QuotedStr('Mindestbestand') + ', '+
                             'CASE WHEN b.in__vrrd<a.minstock then '+QuotedStr('Mindestmenge_unterschritten') + ' ELSE '+QuotedStr('') + ' END AS '+QuotedStr('Bestandskommentar') + ', '+
                             QuotedStr('') + ' AS '+ QuotedStr('Kommentar') + ', '+
                             'COALESCE(SUM(c.b_aantal),0) AS ' + QuotedStr('Rückstand') + ', '+
                             'COALESCE(SUM(d.aant_uit), 0) AS ' + QuotedStr('Gesamtverbrauch') + ' '+
                    'FROM afgart__ a '+
                    'LEFT JOIN afgant__ b ON b.afg__ref = a.afg__ref '+
                    'LEFT JOIN bstlyn__ c ON c.afg__ref = a.afg__ref AND c.vrzvouur<GETDATE() AND c.vrz__tst = '+QuotedStr('1') + ' '+
                    'LEFT JOIN hisafg__ d ON d.afg__ref = a.afg__ref AND MONTH(d.datum___) = MONTH(GETDATE()) '+
                    'WHERE a.kla__rpn = ' + QuotedStr('LBBW') + ' '+
                    'AND  a.zynrefkl <> ' + QuotedStr('') + ' '+
                    'GROUP BY a.zynrefkl, a.afg_oms1, b.in__vrrd, a.per__chk, a.minstock ');
      Query.Open;
      if Assigned(AStream) then begin
         Query.SaveToStream(AStream, sfJSON);
      end;
   Finally
      Query.Free;
      Logic.Free;
   End;
end;
Es sind die ersten 50 Datensätze. Aber ich habe doch gar keine Limitierung eingestellt. Sieht jemand, woran das liegen könnte?

Vielen Dank
Patrick


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:32 Uhr.
Seite 1 von 3  1 23   

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