[PHP] Input uit twee tabellen met elkaar vergelijken?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb in twee verschillende tabellen emailadressen opgeslagen en die wil ik nu allemaal in een keer weergeven, maar dan met alle dubbele invoer verwijderd. Bovendien moet het aantal dubbel ingevoerde emailadressen geteld worden. Deze code heb ik nu maar werkt niet, wat doe ik verkeerd?

Tellen:
PHP:
1
2
3
4
5
6
7
8
9
10
$totaal=0;

$sql = "SELECT tabel1.email, tabel2.email FROM tabel1, tabel2 WHERE tabel1.mail = tabel2.email"; 
$res = mysql_query($sql); 

while($row = mysql_fetch_object($res)){
   $totaal++;
}//while 

echo "Totaal dubbel: $totaal";


Weergeven:
PHP:
11
12
13
14
15
16
$sql = "SELECT DISTINCT tabel1.email, tabel2.email FROM tabel1, tabel2 WHERE tabel1.mail <> tabel2.email"; 
$res = mysql_query($sql); 

while($row = mysql_fetch_object($res)){
   echo "$row->email, ";
}//while 


De bedoeling is dat na vergelijking alle emails maar 1 keer afgedrukt staan.

Het aantal dubbele emails dat geteld zijn moet inclusief de dubbele emails die in 1 tabel zelf zitten zijn en na vergelijking met elkaar.

WIe kan mij zeggen hoe het mprecies moet en wat er fout is aan mijn code.

Thanksss

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

groeperen op email met een count ?

En eventueel een klein php-loopje om de beide resultaten nogmaals te doorlopen.

[ Voor 55% gewijzigd door Bosmonster op 12-01-2005 13:15 ]


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Alle e-mail adressen zonder dubbele (en helaas ook zonder count):

code:
1
SELECT email FROM table1 UNION SELECT email FROM table2;


Je kan hier dus helaas niet mee tellen hoeveel dubbelen je hebt.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nick_S schreef op woensdag 12 januari 2005 @ 13:27:
Alle e-mail adressen zonder dubbele (en helaas ook zonder count):

code:
1
SELECT email FROM table1 UNION SELECT email FROM table2;


Je kan hier dus helaas niet mee tellen hoeveel dubbelen je hebt.
Bedankt.

Ik ga het even proberen, maar dan wel met DISTINCT na beide select om ook dubbele invoer in beide tabellen zelf te verwijderen.

Maar ik wil ook tellen hoeveel het er zijn als iemand dat kan vertellen?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bosmonster schreef op woensdag 12 januari 2005 @ 13:14:
groeperen op email met een count ?

En eventueel een klein php-loopje om de beide resultaten nogmaals te doorlopen.
Hoe had je het precies in je gedachte? Op welke manier worden dubeble invoer nu verwijdert?
Kan je klein stukje code laten zien?
.

Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Als je ipv. UNION dan UNION ALL gebruikt, krijg je ook dubbele. Deze zou je dan met PHP moeten kunnen tellen. Het is namelijk niet mogelijk om over een SQL-statement met UNION nog een GROUP BY en COUNT te gebruiken.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • dajappie
  • Registratie: Januari 2005
  • Laatst online: 13:10
Mooiste zou zijn met SQL, maar kan ook geheel in PHP. Doe een gewone selectie van alle adressen uit beide tabellen en stop deze allemaal in één array en laat daar vervolgens een array_count_values op los. Volgens de php docs: "array_count_values() returns an array using the values of the input array as keys and their frequency in input as values". Deze kan je vervolgens laten zien lijkt me.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Nick_S schreef op woensdag 12 januari 2005 @ 13:27:
Alle e-mail adressen zonder dubbele (en helaas ook zonder count):

code:
1
SELECT email FROM table1 UNION SELECT email FROM table2;


Je kan hier dus helaas niet mee tellen hoeveel dubbelen je hebt.
PHP:
1
2
3
4
5
6
7
$totaal=0;
$sql = "SELECT DISTINCT email FROM tabel1 UNION SELECT DISTINCT email FROM tabel2"; 
$res = mysql_query($sql); 

while($row = mysql_fetch_object($res)){ 
$totaal++;
}//while 

Waarom werkt dit niet, hij geeft aan: mysql_fetch_object(): supplied argument is not a valid MySQL result resourc

[ Voor 21% gewijzigd door Verwijderd op 12-01-2005 14:09 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Je kunt ook gewoon alle adressen uit de tabellen halen en deze in een array stoppen. Vervolgens weet je met count($array) hoeveel het er totaal zijn. Dan doe je een array_unique om alle dubbele te verwijderen en nogmaals een count levert het aantal unieke adressen op.

Met het unieke array kun je de adressen weergeven. Count1 - Count2 levert het aantal dubbelen op lijkt me zo...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • dajappie
  • Registratie: Januari 2005
  • Laatst online: 13:10
Misschien eens hier kijken? http://dev.mysql.com/doc/mysql/en/UNION.html

"If you don't use the keyword ALL for the UNION, all returned rows will be unique, as if you had done a DISTINCT for the total result set. If you specify ALL, you will get all matching rows from all the used SELECT statements."

Dus SELECT ... UNION DISTINCT SELECT ...

Acties:
  • 0 Henk 'm!

  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08 14:36
Waarom gebruik je geen temp-table? Dat lijkt me sneller dan een loop in php.

| Toen / Nu


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
dajappie schreef op woensdag 12 januari 2005 @ 14:09:
Misschien eens hier kijken? http://dev.mysql.com/doc/mysql/en/UNION.html

"If you don't use the keyword ALL for the UNION, all returned rows will be unique, as if you had done a DISTINCT for the total result set. If you specify ALL, you will get all matching rows from all the used SELECT statements."

Dus SELECT ... UNION DISTINCT SELECT ...
Werkt ook niet :/

En voor het weergeven zou dat goed zijn mocht het werken, maar voor het tellen dan moet het niet distinct zijn want alle dubbele invoer moet geteld worden.

Ik ga dan maar die array methode proberen...

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
SuperRembo schreef op woensdag 12 januari 2005 @ 14:18:
Waarom gebruik je geen temp-table? Dat lijkt me sneller dan een loop in php.
Hoe bedoel je precies? Kan je een klein voorbeeldje geven?

Acties:
  • 0 Henk 'm!

  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08 14:36
Het is eigenlijk een manier om een GROUP BY te doen op een UNION query.
PHP:
1
2
3
4
5
mysql_query("CREATE TEMPORARY TABLE temp_union TYPE=HEAP SELECT email FROM table1;");
mysql_query("INSERT INTO temp_union SELECT email FROM table2;");
$result = mysql_query("SELECT email, count(*) FROM temp_union GROUP BY email;");
// display results here
mysql_query("DROP TABLE temp_union;");

| Toen / Nu


Acties:
  • 0 Henk 'm!

Verwijderd

<?
$totaal=0;
$sql = "SELECT DISTINCT email FROM tabel1 UNION SELECT DISTINCT email FROM tabel2";
$res = mysql_query($sql);

while($row = mysql_fetch_object($res)){
$totaal++;
}//while
?>

Waarom werkt dit niet, hij geeft aan: mysql_fetch_object(): supplied argument is not a valid MySQL result resourc
mysql_fetch_object($res)
$res is niet je resource id, $sql is dat.

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
SuperRembo schreef op woensdag 12 januari 2005 @ 14:18:
Waarom gebruik je geen temp-table? Dat lijkt me sneller dan een loop in php.
Je hoeft toch ook niet extreem te loopen in PHP, je kunt gewoon de (suppersnelle) array-functies gebruiken. Het creëren van een temp-tabel lijkt mij juist weer overkill voor deze operatie.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$sql = "SELECT tabel1.email, tabel2.email FROM tabel1, tabel2 ";  
$res = mysql_query($sql);

while($row = mysql_fetch_assoc($res)) //assoc is sneller dan object
{ 
   $emailarray[] = $row['email'];
} 

$total = count($emailarray);
$emailarray = array_unique($emailarray);
$double =  $total - count($emailarray);

echo 'Dubbel: ' .$double;

foreach ($emailarray as $email)
{
  echo '<li>' .$email .'</li>';
}

Dat is één loopje meer dan met een temp-table, het ophalen van de data moet toch in een loop gebeuren. Maar het verschil is dat je slechts één simpele query hoeft uit te voeren. Strax thuis eens even benchmarken wat het verschil is...

[ Voor 5% gewijzigd door T-MOB op 12-01-2005 15:17 ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
T-MOB schreef op woensdag 12 januari 2005 @ 15:17:
[...]


Je hoeft toch ook niet extreem te loopen in PHP, je kunt gewoon de (suppersnelle) array-functies gebruiken. Het creëren van een temp-tabel lijkt mij juist weer overkill voor deze operatie.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$sql = "SELECT tabel1.email, tabel2.email FROM tabel1, tabel2 ";  
$res = mysql_query($sql);

while($row = mysql_fetch_assoc($res)) //assoc is sneller dan object
{ 
   $emailarray[] = $row['email'];
} 

$total = count($emailarray);
$emailarray = array_unique($emailarray);
$double =  $total - count($emailarray);

echo 'Dubbel: ' .$double;

foreach ($emailarray as $email)
{
  echo '<li>' .$email .'</li>';
}

Dat is één loopje meer dan met een temp-table, het ophalen van de data moet toch in een loop gebeuren. Maar het verschil is dat je slechts één simpele query hoeft uit te voeren. Strax thuis eens even benchmarken wat het verschil is...
Het lukt me om alles goed in de array te gooien, alleen als ik array_unique erop toepas dan doet hij het neit en geeft hij deze error:

Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 664944 bytes)

Dit veriwjst naar de regel waar array_unique staat?

Enig idee??

[ Voor 5% gewijzigd door Verwijderd op 12-01-2005 16:02 ]


Acties:
  • 0 Henk 'm!

  • dajappie
  • Registratie: Januari 2005
  • Laatst online: 13:10
De totale hoeveelheid geheugen die PHP mag gebruiken is overschreden, je moet in php.ini de maximale hoeveelheid geheugen beschikbaar voor PHP even verhogen. Je probeert nu nl. alle mailadressen in het geheugen te proppen en er daarna nog operaties op los te laten, wordt wat teveel blijkbaar.

@dajappie: da's dus memory_limit 16M bijvoorbeeld, je moet ff kijken wanneer het weer goed gaat

[ Voor 15% gewijzigd door dajappie op 12-01-2005 16:08 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Of we maken hem wat minder memory intensief...
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<? 

$double = (int);
$sql = "SELECT tabel1.email, tabel2.email FROM tabel1, tabel2 ";   
$res = mysql_query($sql); 

while($row = mysql_fetch_assoc($res)) //assoc is sneller dan object 
{  
   if (in_array($row['email'], $emailarray) { $double++ } else { $emailarray = $row['email']; } 
}

echo 'dubbelen: ' .$double;

foreach($emailarray as $email)
{
  echo '<li>' .$email .'</li>';
}

offtopic:
Je hebt trouwens wel veel emailadressen dan... aan het spammen?? ;)

[ Voor 31% gewijzigd door T-MOB op 12-01-2005 16:17 . Reden: volgorde elementen in_array() ]

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
T-MOB schreef op woensdag 12 januari 2005 @ 16:13:
Of we maken hem wat minder memory intensief...
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<? 

$double = (int);
$sql = "SELECT tabel1.email, tabel2.email FROM tabel1, tabel2 ";   
$res = mysql_query($sql); 

while($row = mysql_fetch_assoc($res)) //assoc is sneller dan object 
{  
   if (in_array($row['email'], $emailarray) { $double++ } else { $emailarray = $row['email']; } 
}

echo 'dubbelen: ' .$double;

foreach($emailarray as $email)
{
  echo '<li>' .$email .'</li>';
}

offtopic:
Je hebt trouwens wel veel emailadressen dan... aan het spammen?? ;)
Nee ik heb zelf een hoop gecopy paste dezelfde achter elkaar en ingevoerd laten lezen om te testen. Wil voor basketball vereniging simpel emailsysteempje maken en probeer zo te testen voor grote aantallen.. Denk dat ik dat niet efficient heb aangepakt, en bovendien ben ik net begonnen in php dus zal ik vast nog meer inefficientheden hebben die memory consumen.

Maar die code doet het ook niet:

Geeft parse error --> $double = (int);

Trouwens hoe moet ik het doen als de tabelnamen niet hetzelfde heten. stel het is tabel1.mails en tabel2.email?

[ Voor 23% gewijzigd door Verwijderd op 12-01-2005 16:43 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
dajappie schreef op woensdag 12 januari 2005 @ 16:06:
De totale hoeveelheid geheugen die PHP mag gebruiken is overschreden, je moet in php.ini de maximale hoeveelheid geheugen beschikbaar voor PHP even verhogen. Je probeert nu nl. alle mailadressen in het geheugen te proppen en er daarna nog operaties op los te laten, wordt wat teveel blijkbaar.

@dajappie: da's dus memory_limit 16M bijvoorbeeld, je moet ff kijken wanneer het weer goed gaat
Ik ben pas begonnen in PHP en ik weet al die dingen nog niet.

Waar kan ik die vinden?

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 16:36
Verwijderd schreef op woensdag 12 januari 2005 @ 16:39:
[...]
Ik ben pas begonnen in PHP en ik weet al die dingen nog niet.
Waar kan ik die vinden?
Je memory limit kun je zetten in je php.ini - het configuratiebestand van PHP op je server. Als je daar niet bij kunt (bijvoorbeld bij een hostingprovider) dan kun je een aantal zaken die daar in staan direct in je script instellen of (in geval van apache) middels een .htacces file. Zo'n .htacces zet je in de directory waarin het script staat. Voor de memory limit zet je daarin
code:
1
2
#php memory setting
php_value memory_limit "12M"


Sorry voor de parse error in mijn script. Als je de regel vervangt door $double = 0; snapt PHP hem wel. Voor je kolomnamenprobleem kun je waarschijnlijk wel uit met een alias.
code:
1
SELECT tab1.kolom, tab2.kol AS kolom FROM tab1, tab2


Maar het kan zijn dat dit niet werkt, nooit nodig gehad omdat ik eigenlijk altijd dezelfde data in dezelfde kolom van dezelfde tabel opsla...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
T-MOB schreef op woensdag 12 januari 2005 @ 17:14:
[...]


Je memory limit kun je zetten in je php.ini - het configuratiebestand van PHP op je server. Als je daar niet bij kunt (bijvoorbeld bij een hostingprovider) dan kun je een aantal zaken die daar in staan direct in je script instellen of (in geval van apache) middels een .htacces file. Zo'n .htacces zet je in de directory waarin het script staat. Voor de memory limit zet je daarin
code:
1
2
#php memory setting
php_value memory_limit "12M"


Sorry voor de parse error in mijn script. Als je de regel vervangt door $double = 0; snapt PHP hem wel. Voor je kolomnamenprobleem kun je waarschijnlijk wel uit met een alias.
code:
1
SELECT tab1.kolom, tab2.kol AS kolom FROM tab1, tab2


Maar het kan zijn dat dit niet werkt, nooit nodig gehad omdat ik eigenlijk altijd dezelfde data in dezelfde kolom van dezelfde tabel opsla...
Bedankt voor de info, ik ga er deze week verder aan kloten :)

Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 11:30

Guldan

Thee-Nerd

Waarom gebruik je bij het tellen niet gewoon mysql_num_rows. Das geloof ik ook sneller dan zoals je het eerst deed. Dan zou het dus zoiets worden.
(ps ook je code ff wat ingekort)
PHP:
1
2
3
4
5
$res = mysql_query("SELECT tabel1.email, tabel2.email FROM tabel1, tabel2 WHERE tabel1.mail  = tabel2.email"; ); 

$totaal = mysql_num_rows($res);

echo "Totaal dubbel: $totaal";


edit: Toch iets te snel geweest. Maar het ging mij erom ff duidelijk te maken dat het kijken hoeveel dubbelen erzijn sneller kan...

[ Voor 22% gewijzigd door Guldan op 12-01-2005 21:45 ]

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?

Pagina: 1