======[SQL] Doppelte Daten====== Ich habe hier mal eine Testtabelle `mytable`. Diese hat eine eindeutige id, dann 2 Schlüsselfelder (`field_1` und `field_2`) sowie ein Feld mit einem Wert (das Feld `value`). ^ mytable ^^^^ ^ id ^ field_1 ^ field_2 ^ value ^ | 1 | A | X | 1 | | 2 | B | X | 2 | | 3 | A | X | 4 | | 4 | C | Z | 8 | | 5 | A | X | 16 | | 6 | C | Z | 32 | =====Herausfinden aller mehrfach vorhandenen Datensätze===== Als erstes versuche ich mal herauszufinden welche Schlüsselpaarkombinationen (`field_1` und `field_2`) mehrfach vorkommen. Dazu kann man die Tabelle nach den Schlüsselfelder gruppieren und Zählen. Wenn es mehr als 1 Eintrag pro Gruppierung hat, dann diese Gruppierung ausgeben. SELECT field_1, field_2 FROM mytable GROUP BY field_1, field_2 HAVING COUNT(*) > 1 -- nur jene auswählen die mehr als ein Datensatz haben Um nun alle Datensätze anzuzeigen deren Schlüsselgruppierungen mehrfach vorkommen, kann man das Resultat von vorher mit der Tabelle zurück verbinden SELECT source.* FROM mytable AS source, ( SELECT field_1, field_2 -- alle Group-Felder FROM mytable GROUP BY field_1, field_2 -- alle Group-Felder HAVING COUNT(*) > 1 -- nur jene auswählen die mehr als ein Datensatz haben ) AS filter WHERE filter.field_1 = source.field_1 -- alle Group-Felder verknüpfen AND filter.field_2 = source.field_2 Wie man sieht, ist die id=2 ausgefiltert, da der Datensatz eindeutig ist. Die nicht Eindeutigen werden ausgegeben ^ Datensätze deren Schlüssel merhfach vorkommt ^^^^ ^ id ^ field_1 ^ field_2 ^ value ^ | 1 | A | X | 1 | | 3 | A | X | 4 | | 4 | C | Z | 8 | | 5 | A | X | 16 | | 6 | C | Z | 32 | ===== Gruppieren, summieren etc ===== Einfach noch einige schöne Dinge die man auf diese Art herleiten kann. Gruppierungen, Prozentberechnung etc. SELECT filter.group_id, source.*, filter.group_sum, (source.value/filter.group_sum) * 100 AS percent_of_group FROM mytable AS source, ( SELECT field_1, field_2, SUM(value) AS group_sum, @rownum := @rownum+1 AS group_id FROM (SELECT @rownum := 0) AS vars, mytable GROUP BY field_1, field_2 ) AS filter WHERE filter.field_1 = source.field_1 AND filter.field_2 = source.field_2 ORDER BY group_id, id; ^ Daten mit Berechnungen über die Gruppe hinweg ^^^^^^^ ^ group_id ^ id ^ field_1 ^ field_2 ^ value ^ group_sum ^ percent_of_group ^ | 1 | 1 | A | X | 1 | 21 | 4.7619 | | 1 | 3 | A | X | 4 | 21 | 19.0476 | | 1 | 5 | A | X | 16 | 21 | 76.1905 | | 2 | 2 | B | X | 2 | 2 | 100.0000 | | 3 | 4 | C | Z | 8 | 40 | 20.0000 | | 3 | 6 | C | Z | 32 | 40 | 80.0000 |