Direkt aufeinander folgende Datensätze gruppieren und zählen

Prengepower

Mitglied
Hallo!

Ich habe eine Datenbank die man sich wie folgt vorstellen könnte:

ID | Datum | Name

Dabei ist das Datum immer unterschiedlich.
Die ID kommt mehrfach vor. Das ist auch richtig so. Allerdings ist es falsch, dass teilweise eine Person direkt nacheinander die selbe ID "bearbeitet" hat..

Also könnte man es sich so vorstellen
ID | Datum | Name
1 1.1 A
1 2.1 A
1 2.1 B
2 1.1 A
3 2.1 C
4 2.1 A
4 2.1 C
4 4.1 A
5 5.1 B
5 7.1 B
6 2.1 A
6 3.1 B
6 3.1 C
7 5.1 A

Aussehen sollte es aber dann wie folgt:

ID | Datum | Name
1 1.1 A
1 2.1 B
2 1.1 A
3 2.1 C
4 2.1 A
4 2.1 C
4 4.1 A
5 5.1 B
6 2.1 A
6 3.1 B
6 3.1 C
7 5.1 A

Gibt es irgendwie einen SQL befehl mit dem ich das anstellen kann?!
Ich möchte das pro Name die Anzahl der Doppelten steht... Also welche mehrfach, nicht direkt aufeinander folgend, einer ID zugeordnet sind...
Sozusagen soll eine tabelle ausgegeben werden, wo ich den namen bekomme, und dazu die anzahl wie oft er sich doppelt mit einer ID befasst hat...

Hoffe das geht iwi mit SQL...
 
Ja es gibt vermutlich einen Befehl. Aber da du uns ja das dbms nicht nennst ist es auch schwer dir zu helfen.

bei Microsoft könntest du mal nach rank over , dense rank oder ähnlichem suchen bei anderen systemen gibt es auch andere lösungen
 
also wie gesagt ich arbeite mit oracle... könnte sonst aber auch mit MySQL arbeiten und da vorher die daten reinfeuern ;)
 
IN MySQL kannst du es mit eigenen Variablen lösen

SQL:
SELECT
	id,
	erstes_datum,
	name,
	COUNT(*) AS anzahl
FROM
	(
		SELECT
			id,	
			datum,
			name,
			@datum := if(@letzteId = id AND @letzterName = name, @datum, datum) AS erstes_datum,
			@letzteId := id,
			@letzterName := name
			
		FROM
			(SELECT @letzteId:=0, @letzterName:='', @datum = '') AS vars,
			(SELECT * FROM test2 ORDER BY id, datum) AS daten1
	) AS daten2
GROUP BY
	id,
	erstes_datum,
	name;
Ergibt dann
Code:
id | erstes_datum | name | anzahl
1 | 1.1 | A | 2
1 | 2.1 | B | 1
2 | 1.1 | A | 1
3 | 2.1 | C | 1
4 | 2.1 | A | 1
4 | 2.1 | C | 1
4 | 4.1 | A | 1
5 | 5.1 | B | 2
6 | 2.1 | A | 1
6 | 3.1 | B | 1
6 | 3.1 | C | 1
7 | 5.1 | A | 1
 
Zuletzt bearbeitet von einem Moderator:
Also das ist ja wirklich schon sehr schön.
Aber lässt sich das Statement noch so anpassen, dass nur die Namen angezeigt werden, die eine ID doppelt hatten?
Sozusagen das folgendes rauskommt:

Id | Name | Anzahl
1 | A | 2 (da direkt aufeinander folgende Dopplungen nicht berücksichtigt werden)
4 | A | 2
 
Ja, hängt am Schluss noch die folgende Zeile dazu und lösch im ersten select das [erstes_datum]
SQL:
HAVING anzahl > 1

Dass sieht dann so aus
SQL:
SELECT
	id,
	name,
	COUNT(*) AS anzahl
FROM
	(
		SELECT
			id,	
			datum,
			name,
			@datum := if(@letzteId = id AND @letzterName = name, @datum, datum) AS erstes_datum,
			@letzteId := id,
			@letzterName := name
			
		FROM
			(SELECT @letzteId:=0, @letzterName:='', @datum = '') AS vars,
			(SELECT * FROM test2 ORDER BY id, datum) AS daten1
	) AS daten2
GROUP BY
	id,
	erstes_datum,
	name
HAVING anzahl > 1
 
Zuletzt bearbeitet von einem Moderator:
okay cool aber da wird jetzt noch nicht herausgefilter, wenn 2 namen sich direkt hintereinander mit einer ID beschäftigen oder? das sollte ja sein.. es soll nur gezählt werden wenn zwischen 2 namen noch ein anderer ist ;)

aber shconmal danke :)
 
Aso. Die Anzahl sollte also nicht auf die 'Unterdrückten' gezählt werden...

1) Unterdrücken von aufeinanderfolgenden Usern bei gleicher id
2) Anzahl der Kombinationen id & name ohne die unterdrückten Einträge

Das ergibt etwa sowas
SQL:
-- Zählen der Kombination id, name
SELECT
	id, 
	name,
	count(*) AS anzahl
FROM
	(
		-- aufeinanderfolgende namen mit gleicher id und gleichem erstes_datum unterdrücken
		SELECT
			id,
			erstes_datum,
			name
		FROM
			(
				-- erstes_datum ermiteln
				SELECT
					id,	
					datum,
					name,
					@datum := if(@letzteId = id AND @letzterName = name, @datum, datum) AS erstes_datum,
					@letzteId := id,
					@letzterName := name
					
				FROM
					(SELECT @letzteId:=0, @letzterName:='', @datum = '') AS vars,
					(SELECT * FROM test2 ORDER BY id, datum) AS daten
			) AS daten
		GROUP BY
			id,
			erstes_datum,
			name
	) AS daten
GROUP BY
	id, 
	name
 
Zuletzt bearbeitet von einem Moderator:

Neue Beiträge

Zurück