GROUP BY gegevens verzamelen?
1. Kees - kees&hotmail.com - Groningen - ? - ?
2. Kees van Vliet - kees&hotmail.com - ? - 23-01-2010 - ?
3. Jan - [email protected] - Utrecht - ? - ?
4. Kees - kees&hotmail.com - Groningen - ? - Man
Uiteraard zijn er nog een aantal velden die komen na het laatste ? en is de hele database inmiddels bij 80.000 records. Ik wil graag de MySQL-database groepen op basis van e-mailadressen. Daarbij wil ik ook alle beschikbare gegevens dan van iemand tonen. Als ik bijvoorbeeld record 1 neem, weet ik niet zijn geboortedatum en geslacht, bij record 2 weet ik weer niet zijn woonplaats etc. terwijl we het wel over hetzelfde e-mailadressen spreken. Bovendien weet ik ook bij record 2 de achternaam van de persoon.
Weet iemand hier een oplossing voor met MySQL?
--------------------
GROUP BY zal de eerste gegevens nemen die het tegenkomt.
Maar wat wil je zelf doen, indien je tegenstrijdige data hebt?
Moet het "Kees" zijn, of "Kees van Vliet"? Hoe wil je dit automatiseren?
Wat je eventueel wel kan doen, is enkel de lege velden vervangen.
bv. als volgt:
- Je selecteert alle records. ORDER BY email (niet GROUP BY email). Dit zorgt er voor dat dubbels mooi naast mekaar staan, bij het fetchen
- dan kan je met php de ontbrekende gegevens invullen, in de
while($row = mysql_fetch_assoc($res)) { ...
lus.
Interesse in deze oplossing?
Iemand een beter idee?
Gewijzigd op 24/04/2012 17:28:58 door Kris Peeters
De bedoeling precies is om een CSV-bestand hiervan te genereren met daarin alle gegevens. Het liefst zou ik dit op MySQL-niveau willen en liever niet met PHP, al is het maar om de snelheid erin te houden. Het liefst wil ik de hoogste ID pakken, aangezien deze het compleetst waarschijnlijk is ingevuld. Er zitten nu namelijk checks op het formulier dat controleert of het allemaal goed is ingevuld.
Ik ben geneigd je redenering niet te volgen, wat de snelheid betreft.
In principe moet je dit maar 1 keer echt uitvoeren. Who cares dat dit wat langer duurt?
Maar vooral: je zit met 80.000 records. Dit lijkt me vrij veel, qua virtueel geheugen. Ik denk dat je vlug "out of memory" gaat gaan.
Het is ook interessant dat je het naar file wil schrijven.
Je zou in schijven kunnen werken: gelijdelijk aan de csv-file genereren.
Iets wat op file staat, vereist geen virtueel geheugen.
Gewijzigd op 24/04/2012 19:34:54 door Ger van Steenderen
GROUP BY is voor het groeperen van gegevens waarbij je een kolom sommmeert (SUM) telt (COUNT) en MIN MAX en dergelijke. GROUP BY is niet om te filteren en/of maar 1 record als resultaat te hebben. Helaas wordt dit vaak misbruikt en later worden het dan spaghetti resultaten. Je voert zoals Ger al zei je gegevens onjuist op, je INSERT misschien in plaats van UPDATE?? Zoek eens een tutorial hier over gegevensverwerking.
De reactie van Aad klopt ook.
Maar denk ook: de voornaamste reden waarom je deftig filtert op mySQL-niveau is om de data-trafiek database -> apache (php) zo klein mogelijk te houden.
Je hebt echter de data van alle records nodig. Dan kan je even goed een beetje minder energie steken in de sql query
-----
Ik heb iets uitgewerkt. (nogal quick & dirty, voorlopig)
Probeer dit al eens uit. Volgens mij doet dit al bijna wat je nodig hebt.
Best even testen op een aparte test-database
Ik stuur een sql export mee.
Dan nog exporteren naar csv ...
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
/*
CREATE TABLE IF NOT EXISTS users (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
username varchar(60) NOT NULL DEFAULT '',
pass varchar(32) NOT NULL DEFAULT '',
email varchar(64) DEFAULT '',
mode tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO users (id, username, pass, email, mode) VALUES
(2, 'wrupucicha', '7ca62315c9b9e0b46d7fb4aaf287bd30', 'wrupucicha@localhost', 0),
(3, 'tranubiwr', '', 'tranubiwr@localhost', 0),
(4, 'lonehesac', '72540b4a4eb73db2b1cd0d30b5e79cac', 'lonehesac@localhost', 0),
(5, 'buthiueph', '33330f42a4de4bee9c10b4f702fb8b9b', 'buthiueph@localhost', 0),
(6, 'speshigut', '2735cbc0677f66f6b5c8ef5ac009bd82', 'speshigut@localhost', 0),
(7, 'driswu', '11a97797dc59536a95949bb4f9d779b3', 'driswu@localhost', 0),
(8, 'kamecrolac', '77813980d48a32d642353fd8876ccf68', 'kamecrolac@localhost', 0),
(9, 'stiphislod', 'de6c1dbdd7c20b692516fdafc281bc59', 'stiphislod@localhost', 0),
(10, 'drukesh', '1ea73311475652082690252f4e0b8a4c', 'drukesh@localhost', 0),
(11, 'hemutihefro', 'bfa0c373b636831d3bd35f6a412011e5', 'hemutihefro@localhost', 0),
(12, 'buthiueph', '333b', 'buthiueph@localhost', 0),
(13, 'Tom', '', 'driswu@localhost', 0),
(14, 'Freddy', 'dcd0ff2c99c6b7f384e84e4304a27f98', 'tranubiwr@localhost', 0);
*/
$records = array();
$temp_record = null;
$max_records = 100;
$con = mysql_connect( 'localhost', 'root', '' );
mysql_select_db('phphulp');
$sql = "
SELECT
id, username, pass, email
FROM users
ORDER BY email, id DESC
";
$res = mysql_query($sql);
while ($row = mysql_fetch_assoc($res)) {
add_record($row, $temp_record, $records);
}
// save last record
save_record($temp_record);
echo '<pre>' . print_r($records, TRUE) . '</pre>';
function add_record($row, &$temp_record, &$records) {
if (empty($temp_record)) {
$temp_record = $row;
}
if ($row['email'] === $temp_record['email']) {
// alle velden van $record overlopen, indien een veld leeg is, proberen we het veld uit $row te halen
foreach ($temp_record as $key=>$field) {
if ($key === 'email') {
continue;
}
if (is_empty($field)) {
$temp_record[$key] = $row[$key];
}
}
}
else { // wwe hebben een nieuw record, met verschillend e-mail-adres. Nu pas gaan we het vorige recors opslaan
save_record($temp_record);
$temp_record = $row;
}
}
function is_empty($string) {
// ik zet het in een aparte functie. Indien nodig kan dit gemakkelijk geoptimaliseerd worden
return
trim($string) === ''
? TRUE
: FALSE;
}
function save_record(&$record) {
global $records; // een beetje quick & dirty. ... tja ...
$records[count($records)] = $record;
}
?>
/*
CREATE TABLE IF NOT EXISTS users (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
username varchar(60) NOT NULL DEFAULT '',
pass varchar(32) NOT NULL DEFAULT '',
email varchar(64) DEFAULT '',
mode tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO users (id, username, pass, email, mode) VALUES
(2, 'wrupucicha', '7ca62315c9b9e0b46d7fb4aaf287bd30', 'wrupucicha@localhost', 0),
(3, 'tranubiwr', '', 'tranubiwr@localhost', 0),
(4, 'lonehesac', '72540b4a4eb73db2b1cd0d30b5e79cac', 'lonehesac@localhost', 0),
(5, 'buthiueph', '33330f42a4de4bee9c10b4f702fb8b9b', 'buthiueph@localhost', 0),
(6, 'speshigut', '2735cbc0677f66f6b5c8ef5ac009bd82', 'speshigut@localhost', 0),
(7, 'driswu', '11a97797dc59536a95949bb4f9d779b3', 'driswu@localhost', 0),
(8, 'kamecrolac', '77813980d48a32d642353fd8876ccf68', 'kamecrolac@localhost', 0),
(9, 'stiphislod', 'de6c1dbdd7c20b692516fdafc281bc59', 'stiphislod@localhost', 0),
(10, 'drukesh', '1ea73311475652082690252f4e0b8a4c', 'drukesh@localhost', 0),
(11, 'hemutihefro', 'bfa0c373b636831d3bd35f6a412011e5', 'hemutihefro@localhost', 0),
(12, 'buthiueph', '333b', 'buthiueph@localhost', 0),
(13, 'Tom', '', 'driswu@localhost', 0),
(14, 'Freddy', 'dcd0ff2c99c6b7f384e84e4304a27f98', 'tranubiwr@localhost', 0);
*/
$records = array();
$temp_record = null;
$max_records = 100;
$con = mysql_connect( 'localhost', 'root', '' );
mysql_select_db('phphulp');
$sql = "
SELECT
id, username, pass, email
FROM users
ORDER BY email, id DESC
";
$res = mysql_query($sql);
while ($row = mysql_fetch_assoc($res)) {
add_record($row, $temp_record, $records);
}
// save last record
save_record($temp_record);
echo '<pre>' . print_r($records, TRUE) . '</pre>';
function add_record($row, &$temp_record, &$records) {
if (empty($temp_record)) {
$temp_record = $row;
}
if ($row['email'] === $temp_record['email']) {
// alle velden van $record overlopen, indien een veld leeg is, proberen we het veld uit $row te halen
foreach ($temp_record as $key=>$field) {
if ($key === 'email') {
continue;
}
if (is_empty($field)) {
$temp_record[$key] = $row[$key];
}
}
}
else { // wwe hebben een nieuw record, met verschillend e-mail-adres. Nu pas gaan we het vorige recors opslaan
save_record($temp_record);
$temp_record = $row;
}
}
function is_empty($string) {
// ik zet het in een aparte functie. Indien nodig kan dit gemakkelijk geoptimaliseerd worden
return
trim($string) === ''
? TRUE
: FALSE;
}
function save_record(&$record) {
global $records; // een beetje quick & dirty. ... tja ...
$records[count($records)] = $record;
}
?>
Gewijzigd op 24/04/2012 21:08:21 door Kris Peeters
SELECT * , MAX( provincie ) , MAX( geboortejaar ) , MAX( geboortemaand ) , MAX( straat ) , max( nummer )
FROM `contacts`
WHERE optin = '1'
GROUP BY email
ORDER BY email
Op deze manier wordt dan gekeken of er bij het veld provincie iets is ingevuld. Als blijkt dat bijvoorbeeld bij 1 van de 5 maar Utrecht staat en de andere niets dan wordt Utrecht getoond. Ik ga er dan wel vanuit dat men dan niet bijvoorbeeld Utrecht en Groningen ingevuld heeft bij het veld provincie. Anders wordt het sowieso moeilijk controleren.
Gewijzigd op 25/04/2012 11:38:30 door Ger van Steenderen