AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Daten per SQL gruppieren

Ein Thema von norwegen60 · begonnen am 8. Apr 2017 · letzter Beitrag vom 10. Apr 2017
Antwort Antwort
Seite 1 von 3  1 23      
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#1

Daten per SQL gruppieren

  Alt 8. Apr 2017, 08:49
Datenbank: mssql • Version: 2008 • Zugriff über: unidac
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 'F05323690AND '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
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Daten per SQL gruppieren

  Alt 8. Apr 2017, 10:26
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
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

AW: Daten per SQL gruppieren

  Alt 8. Apr 2017, 10:42
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.
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#4

AW: Daten per SQL gruppieren

  Alt 8. Apr 2017, 11:25
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
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

AW: Daten per SQL gruppieren

  Alt 8. Apr 2017, 12:49
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

AW: Daten per SQL gruppieren

  Alt 8. Apr 2017, 17:36
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
$2B or not $2B
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
505 Beiträge
 
Delphi 12 Athens
 
#7

AW: Daten per SQL gruppieren

  Alt 9. Apr 2017, 08:30
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.
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

AW: Daten per SQL gruppieren

  Alt 9. Apr 2017, 08:54
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)
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#9

AW: Daten per SQL gruppieren

  Alt 9. Apr 2017, 09:03
Moin...
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.

Geändert von haentschman ( 9. Apr 2017 um 09:20 Uhr)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#10

AW: Daten per SQL gruppieren

  Alt 9. Apr 2017, 12:06
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.
Gruß, Jo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 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