SQL-Abfrage - Anzahl der Wechsel zählen
Hallo zusammen,
lässt sich folgendes mit einem SQL-Select umsetzen?
Gegeben sei eine Tabelle xyz mit der Spalte 1:
Ich möchte die Anzahl der Wechsel wissen. Das gewünschte Ergebnis wäre 5:
Lässt sich das mit einem SQL-Select lösen? Ein Group by funktioniert beispielweise nicht, das würde zum Ergebnis 4 führen:
Pseudocode:
Dankeschön.
lässt sich folgendes mit einem SQL-Select umsetzen?
Gegeben sei eine Tabelle xyz mit der Spalte 1:
Spalte1
a
b
b
c
b
b
b
b
d
b
b
Ich möchte die Anzahl der Wechsel wissen. Das gewünschte Ergebnis wäre 5:
a - > b
b -> c
c -> b
b -> d
d -> b
Lässt sich das mit einem SQL-Select lösen? Ein Group by funktioniert beispielweise nicht, das würde zum Ergebnis 4 führen:
a
b
c
d
Pseudocode:
if "nächster Wert" ungleich "aktueller Wert" then
1
else
0
Dankeschön.
Please also mark the comments that contributed to the solution of the article
Content-ID: 324452
Url: https://administrator.de/forum/sql-abfrage-anzahl-der-wechsel-zaehlen-324452.html
Printed on: May 12, 2025 at 07:05 o'clock
15 Comments
Latest comment
prinzipiell würde sich sowas über FETCH & Cursor lösen lassen (https://msdn.microsoft.com/de-de/library/ms180152.aspx)
Aber was willst du denn am Ende damit erreichen? Klingt irgendwie für mich erst mal wenig Sinnvoll, als Aufgabe für einen SQL
Aber was willst du denn am Ende damit erreichen? Klingt irgendwie für mich erst mal wenig Sinnvoll, als Aufgabe für einen SQL
Ist die Entry No. lückenlos? Dann ginge
Ist die Reihenfolge nicht lückenlos oder liegt ein Zeitstempel zugrunde würde ich mit ROW_NUMBER() arbeiten und darauf joinen. Das gibts allerdings bei MySQL nicht.
Von einem Cursor würde ich generell abraten, allein schon wegen der gruseligen Performance.
SELECT count(*) AS anzahl_wechsel
FROM tabelle t1
INNER JOIN tabelle t2
ON t1.entry_no = t2.entry_no + 1
WHERE t1.spalte1 != t2.spalte1
Ist die Reihenfolge nicht lückenlos oder liegt ein Zeitstempel zugrunde würde ich mit ROW_NUMBER() arbeiten und darauf joinen. Das gibts allerdings bei MySQL nicht.
Von einem Cursor würde ich generell abraten, allein schon wegen der gruseligen Performance.
naja im Grunde genau wie du es beschrieben hast.
du machst ne SP, mit der machst du einen Select auf die Daten die du haben willst und iterierst dann durch das Resultset durch
Es wäre noch immer interessant, was du damit erreichen willst, weil davon auch abhängen würde, was man in die SP schreibt
du machst ne SP, mit der machst du einen Select auf die Daten die du haben willst und iterierst dann durch das Resultset durch
Es wäre noch immer interessant, was du damit erreichen willst, weil davon auch abhängen würde, was man in die SP schreibt
OK jetzt wissen wir leider nicht mehr als davor 
Was ist der Sinn dahinter? Warum muss man wissen, wie oft da gewechselt wurde?
Verstehe mich nicht falsch, aber das sieht mir stark nach dem Typischen "Ich hatte eine Idee, wie ich was machen will, und sehe jetzt den Wald vor lauter Bäumen nicht mehr".
Vermutlich gibt es für das Problem eine Sinnvollere Lösung als das.
Nur als Info: Was du vorhast, bedeutet, das du bei jedem Aufruf der SP durch die komplette Tabelle(oder der Range davon) Zeilenweise durchratterst. Ich weiss nicht um was für Dimensionen es sich hier handelt, aber ganz prinzipiell ist das schrecklich unperformant und von der Vorgehensweise gruselig
Was ist der Sinn dahinter? Warum muss man wissen, wie oft da gewechselt wurde?
Verstehe mich nicht falsch, aber das sieht mir stark nach dem Typischen "Ich hatte eine Idee, wie ich was machen will, und sehe jetzt den Wald vor lauter Bäumen nicht mehr".
Vermutlich gibt es für das Problem eine Sinnvollere Lösung als das.
Nur als Info: Was du vorhast, bedeutet, das du bei jedem Aufruf der SP durch die komplette Tabelle(oder der Range davon) Zeilenweise durchratterst. Ich weiss nicht um was für Dimensionen es sich hier handelt, aber ganz prinzipiell ist das schrecklich unperformant und von der Vorgehensweise gruselig
Na dann läßt sich das recht elegant lösen, hier mal ein Vorschlag
Ich bin jetzt mal davon ausgegangen das die Wechsel von [Entry Type] gezählt werden sollen. [Entry No_] bestimmt die Reihenfolge, [Item No_] ist vermutlich dein Fremdschlüssel auf irgendwas, da macht eine Partitionierung eventuell Sinn.
Grundsätzlich gibt es mehrere Wege das zu lösen und anzupassen, mit MSSQL sollte sich das so am performantesten umsetzen lassen.
WITH t AS (
SELECT ROW_NUMBER() OVER (PARTITION BY [Item No_] ORDER BY [Entry No_]) AS zeile,
[Item No_],
[Entry Type]
FROM tabelle
)
SELECT t1.[Item No_],
count(*) AS anzahl_wechsel
FROM t t1
INNER JOIN t t2
ON t1.[Item No_] = t2.[Item No_]
AND t1.zeile = t2.zeile + 1
WHERE t1.[Entry Type] != t2.[Entry Type]
GROUP BY t1.[Item No_]
Grundsätzlich gibt es mehrere Wege das zu lösen und anzupassen, mit MSSQL sollte sich das so am performantesten umsetzen lassen.
Moin ukulele-7,
wäre auch genau meine Strategie gewesen, wenn kein LEAD()/LAG() zur Verfügung steht.
Allerdings hätte ich nach der Beschreibung erwartet, dass die Wechsel von "Document_No_" Inhalt der Recherche sind und das Statement so geändert.
Aber da der Beitrag inwischen als "Gelöst" markiert ist, hab ich mich wohl verlesen.
@Cire48
Dringendst zu empfehlen ist noch einer sinnvolle Einschränkung mit einer WHERE-Clause in einer neuen Zeile 07 - z.B. auf einen Zeitraum BETWEEN... oder bestimmte Item_No_.
Und eine andere Variante auch mit einer gewissen Aussagekraft wäre eine Erweiterung der CTE um ein Feld "Jahr_Monat" und eine Auswertung der Wechsel nicht über einzeln aufgeführte Item_No, sondern nach "Wechseln pro Jahr/Monat".
Grüße
Biber
wäre auch genau meine Strategie gewesen, wenn kein LEAD()/LAG() zur Verfügung steht.
Allerdings hätte ich nach der Beschreibung erwartet, dass die Wechsel von "Document_No_" Inhalt der Recherche sind und das Statement so geändert.
WITH t AS
(
SELECT row_number() OVER (PARTITION BY [Item No_] ORDER BY [Entry No_]) AS zeile
, [Item No_]
, [Document_No_]
FROM tabelle
)
SELECT t1.[Item No_]
, count(*) AS anzahl_wechsel
FROM t t1
INNER JOIN t t2
ON t1.[Item No_] = t2.[Item No_]
AND t1.zeile = t2.zeile + 1
WHERE t1.[Document_No_] != t2.[Document_No_]
GROUP BY t1.[Item No_];
Aber da der Beitrag inwischen als "Gelöst" markiert ist, hab ich mich wohl verlesen.
@Cire48
Dringendst zu empfehlen ist noch einer sinnvolle Einschränkung mit einer WHERE-Clause in einer neuen Zeile 07 - z.B. auf einen Zeitraum BETWEEN... oder bestimmte Item_No_.
Und eine andere Variante auch mit einer gewissen Aussagekraft wäre eine Erweiterung der CTE um ein Feld "Jahr_Monat" und eine Auswertung der Wechsel nicht über einzeln aufgeführte Item_No, sondern nach "Wechseln pro Jahr/Monat".
Grüße
Biber