|   Having / Group by / Aggregieren - Kompliziertere SQL Abfragen in einer
TabelleVertiefungen & ÜbungenGerade beim Aggregieren von Daten zeigen sich die stärken von relationalen
DBMS und häufen sich auch die Schwierigkeiten was SQL Abfragen angeht.Deshalb hier ein paar Beispiele wie Daten agregiert werden können
 
Eine Testtabelle mit Daten
 CREATE TABLE `preis` (
 `id` int(10) unsigned NOT NULL auto_increment,
 `user_id` int(10) unsigned NOT NULL default '0',
 `value` decimal(12,2) NOT NULL default '0.00',
 `info` varchar(250) NOT NULL default '',
 PRIMARY KEY  (`id`)
 ) TYPE=MyISAM
 
 #
 # Daten für Tabelle `preis`
 #
 
 INSERT INTO `preis` VALUES (1001, 12, '12.00', 'Auto');
 INSERT INTO `preis` VALUES (1002, 12, '112.00', 'Auto');
 INSERT INTO `preis` VALUES (1003, 12, '212.00', 'Auto');
 INSERT INTO `preis` VALUES (1004, 12, '312.00', 'Haus');
 INSERT INTO `preis` VALUES (1005, 12, '412.00', 'Haus');
 INSERT INTO `preis` VALUES (1006, 12, '512.00', 'Auto');
 INSERT INTO `preis` VALUES (1007, 12, '612.00', 'Kino');
 INSERT INTO `preis` VALUES (1008, 12, '62.00', 'Haus');
 INSERT INTO `preis` VALUES (1009, 12, '512.00', 'Auto');
 INSERT INTO `preis` VALUES (1010, 12, '62.00', 'Haus');
 
 Select mit Group by und havingMitGROUP BYaggregiert man Zeilen aufaggregieren, d.h. man
fasst Zeilen zusammen.Mit Hilfe von
 HAVINGgrenzt man die gruppierte Ergebnismenge
ein.
Einfachste Anwendung:
 
 SELECT count(*),info
 FROM preis
 GROUP BY info
 
 SELECT count(*),info
 FROM preis
 GROUP BY info
 HAVING count(*)>2
 
Alle Agregierfunktionen dürfen bei Group by verwendet werden:
 
 SELECT info, sum( value ) , avg( value ) , count( * ) , min( value ) , max(
 value )
 FROM preis
 WHERE user_id = 12
 GROUP BY info
 HAVING min( value ) > 100
 
 
     Aufgaben:Wie kann man diesen Subselect (der erst ab version 4.1 gehen soll!)
umschreiben?
 SELECT  *
 FROM preis
 WHERE
 id IN (
 SELECT id
 FROM preis
 WHERE value > 100
 )
 
Tip: Selfjoin
 
Wie können Doubletten (erkennbar an gleichem Value user_id und Info)
raussuchen? 
 select count(*),
 user_id,
 value,
 info
 from preis
 group by user_id,
 value,
 info
 having count(*) >1
 
Kann man das Löchen der Datensätze (nicht nur das finden!) auch automatisieren?
 
 
 Hint: Group by macht hin und wieder bei Date/Time Feldern Pobleme Abhilfe schaft
hier SEC_TO_TIME(SUM(TIME_TO_SEC(Datums_Time_Feld))) 
 
 
 |