Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Daten per SQL gruppieren (https://www.delphipraxis.net/192322-daten-per-sql-gruppieren.html)

norwegen60 8. Apr 2017 07:49

Datenbank: mssql • Version: 2008 • Zugriff über: unidac

Daten per SQL gruppieren
 
Hallo zusammen,

ich habe folgende Daten
Code:
SerNr      Typ        Status
F05323690   MLC10U100   S
F05323691   MLC10U100   S
F05323692   MLC10U100   R
F05323693   MLC10U100   S
F05323694   MLC10U100   S
und möchte sie so gruppieren, dass ich folgende Ausgabe bekommen
Code:
Min(SerNr)  Typ        Status  Anzahl
F05323690    MLC10U100   S       2
F05323692    MLC10U100   R       1 
F05323693    MLC10U100   S       2
Mit einer einfachen
Delphi-Quellcode:
SELECT min(SerNr), Typ, Status, count(SerNr)
FROM Ser_nr
WHERE SerNr BETWEEN 'F05323690' AND 'F05323695'
group by Typ, Status
order by min(SerNr)
sähe das Ergebnis so aus
Code:
Min(SerNr)  Typ        Status  Anzahl
F05323690    MLC10U100   S       4
F05323692    MLC10U100   R       1
Hintergrund ist, dass ein Typenschldprogramm die Daten so übergeben bekommt.
Im 1. Fall würde es die Serien-Nr.
  • F05323690 bis F05323691 mit Status S, (Anzahl 2 = 2 fortlaufende Serien-Nr.)
  • F05323692 mit Status R
  • F05323693 bis F05323694 wieder mit Status S
drucken
Im 2. - falschen Fall - würde es die Serien-Nr.
  • F05323690 bis F05323693 mit Status S, (Anzahl 4 = 4 fortlaufende Serien-Nr.)
  • F05323692 mit Status R
drucken. d.h. F05323694 wird gar nicht gedruckt und F05323692 einmal mit Status S und einmal mit Status R

Hat einer einen Tip
Danke
Gerd

p80286 8. Apr 2017 09:26

AW: Daten per SQL gruppieren
 
Zitat:

Zitat von norwegen60 (Beitrag 1366845)
d.h. F05323694 wird gar nicht gedruckt und F05323692 einmal mit Status S und einmal mit Status R

Das verstehe ich nicht!
Sowohl in der gewünschten als auch in der falschen Ausgabe taucht die F05323694 nicht auf, und wird darum auch nicht gedruckt.

Gruß
K-H

jfheins 8. Apr 2017 09:42

AW: Daten per SQL gruppieren
 
Ich glaube, der Drucker bekommt eine Seriennummer und eine Anzahl und zählt die Seriennummer dann automatisch hoch beim Drucken.

Zum Problem: In SQL ist die Reihenfolge der Zeilen nicht definiert. Dein Tool zeigt dir das zwar meistens reproduzierbar nett an, aber du darfst dich darauf nicht verlassen, dass das reproduzierbar ist.
Demzufolge kannst du per group-by auch nicht nur "aufeinanderfolgende Zeilen" gruppieren.

Lösung wäre eine extra Spalte, in die man für (aufeinanderfolgende Seriennummern/gleicher Typ/gleicher Status) Kombinationen die gleiche Zahl rein schreibt. Dann einfach nur nach dieser Spalte gruppieren. Oder du holst dir alle Datensätze nach Seriennummer sortiert und machst diesen Schritt im SQL Client.

norwegen60 8. Apr 2017 10:25

AW: Daten per SQL gruppieren
 
Zitat:

Zitat von jfheins (Beitrag 1366850)
Ich glaube, der Drucker bekommt eine Seriennummer und eine Anzahl und zählt die Seriennummer dann automatisch hoch beim Drucken.

Stimmt. Über Anzahl erfährt das Typenschildprogramm wie viele fortlaufenden Nr. gedruckt werden sollen

"Mein Tool" das die Daten anzeigt ist schon ein SQL und was mir fehlt ist ein Kommando das erkennt wenn innerhalb einer Gruppe ein "schwarzes Schaf" ist das die Gruppe unterbricht.
In der Realität gibt es auch die Serien-Nr. F05323692 mit Status S in der DB. Viele Datensätze später gibt es dieselbe Serien-Nr. aber auch mit Status R und über das Unter-SQL suche ich zuerst mal den letzten und damit aktuelle gültigen Eintrag zu einer Serien-Nr.
Das SQL für die die erste Tabelle sieht in Wirklichkeit so aus
Code:
SELECT s.sernr, s.Typ, s.[Status]
FROM Ser_nr s
INNER JOIN (SELECT S1.SerNr, Max(S1.ID) AS MaxID
            FROM Ser_Nr AS S1
            WHERE s1.SerNr BETWEEN 'F05323690' AND 'F05323694'
            GROUP BY S1.SerNr) AS S3
         ON s.ID = S3.MaxID
order by s.SerNr

jfheins 8. Apr 2017 11:49

AW: Daten per SQL gruppieren
 
Also eine Lösung wäre ja auch, das Feature mit dem automatischen Hochzählen nicht zu benutzen und alle Datensätze einzeln zum Drucker zu schicken. :stupid:

himitsu 8. Apr 2017 16:36

AW: Daten per SQL gruppieren
 
Joar, also entweder eine WindowFnction schreiben, die bei Unterschied um 1 hoch zählt

das alles manuell in einer Stored Proc lösen

oder erstmal im Hauptselect die Ersten raussuchen (Alles, wo direkt vor sich etwas Unterschiedliches liegt
und dann z.B. in einem rekursiven Select alles suchen, wo davor etwas Gleiches liegt und das an den er jeweils ersten Datensatz dran joinen.

oder es alt Clientseitig machen

norwegen60 9. Apr 2017 07:30

AW: Daten per SQL gruppieren
 
Zitat:

Zitat von jfheins (Beitrag 1366863)
Also eine Lösung wäre ja auch, das Feature mit dem automatischen Hochzählen nicht zu benutzen und alle Datensätze einzeln zum Drucker zu schicken. :stupid:

So hatte ich es auch schon ausprobiert.

Nachteil:
Die Typenschilder sind auf Endlosmaterial und werden vom Drucker geschnitten.
Erzeugt man für jeden Nr. einen Eintrag, wird jeder Eintrag einzeln bearbeitet, d.h. die Nr wird gedruckt, rausgeschoben, abgeschnitten, wieder zurück gezogen und das nächste gedruckt.
Übergiebt man ein Band, wird das komplette Band fortflaufend gedruckt und geschnitten und erst bei einem neuen Band (oder Einzeleintrag) zurückgezogen.
Und manchmal bis zu 2000 Typenschilder gedruckt werden und die in aller Regel als Band vorliegen, ist die Einzelübergabe ungünstig.
Bisher habe ich das so realsiert, dass ich Delphi durch das SQL Ergebniss laufen und gruppieren lasse. Da jetzt ein neues Labelprogramm mit anderem Befehlsaufbau dazu kommt, wollte ich den Job komplett in MsSQL auslagen
Aber wenns nicht geht mach ich eben weiter wie bisher.

Danke trotzdem.

himitsu 9. Apr 2017 07:54

AW: Daten per SQL gruppieren
 
Wie übergibst du das denn an den Drucker?

Nur weil du das im Programm "einzeln" verarbeitest, muß es auch nicht einzeln zum Drucker.
Du kannst das ja sammeln und dann gemeinsam zum Drucker schicken.

Falls die Schnittstelle das DataSet entgegen nimmt, dann entweder die Daten holen und in ein Memory-DataSet umkopieren
oder z.B. CachedUpdates=True und dann das DataSet bearbeiten (Edit/Delete) bevor es an den Drucker geht. (natürlich hinteher das CancelUpdates nicht vergessen)

haentschman 9. Apr 2017 08:03

AW: Daten per SQL gruppieren
 
Moin...8-)
Zitat:

Wie übergibst du das denn an den Drucker?
...bei Labeldruckern würde ich mich auf SDK des Druckers verlassen. Da hast das Schneiden komplett im Griff... nach jedem 5. Etikett oder 10. Etikett oder nach Wechsel der Nummer oder beim Ende des Auftrages... Für das Etikett gibt es eine Vorlage...Daten rein...fertsch. :thumb:

jobo 9. Apr 2017 11:06

AW: Daten per SQL gruppieren
 
Man muss ein Zwischenergebnis hinbekommen, dass es ermöglicht einer gewünschten Gruppe von Werten ein eindeutiges Gruppierungsmerkmal zuzuordnen.

Ist das gelungen, dann ist der Rest einfach Standard Group by.

Code:
select GroupedSerNr, Typ, Status, Count(*)
  from (
       SELECT SerNr, Typ, Status,
              case
                  when LAG(status,1,'R') OVER(ORDER BY SerNR) = status
                  then LAG(SerNR)       OVER(ORDER BY SerNR)
                  else serNr  
              end AS GroupedSerNr
         FROM daten
        WHERE SerNr BETWEEN 'F05323690' AND 'F05323695'
       ) x
group by GroupedSerNr, Typ, Status
order by GroupedSerNr
Das Inner Select erzeugt die Unterscheidung der Gruppe über das "Detektieren" einer Wertänderung von Status und abhängig davon dann die Auswahl eines eindeutigen Gruppenmerkmals, hier die schon vorhandene oder vorige SerNr.

Offset und Defaultangabe von Lag(Status...) muss ggF. angepasst werden.


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

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