Toon posts:

[PHP+MySQL] Alternatief voor UNION?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Weet iemand een alternatief of workaround voor UNION in MySQL? Ik wil data uit 2 tabellen samengevoegd uitlezen, echter de server waarop dit moet draaien ondersteunt nog geen UNION.
Het moet onder elkaar samengevoegd worden, dus aan JOIN heb ik volgens mij niets.

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 09:53
Dat staat in de comments van de mysql-reference:
Bron
An alternative, rather simpler (especially with very complex select statements) way to 'use union' in 3.x might be the following:

Build a nice union query. (save it somewhere, so you can use that if you upgrade)
If you would say that query was '(*cool_select_statement_1*) UNION (*cool_select_statement_2*) *order_and_group_by_stuff*'.
You could make an replacement set of query's like this:
CREATE TEMPORARY TABLE temp_union TYPE=HEAP *cool_select_statement_1*;
INSERT INTO temp_union *cool_select_statement_2*;
SELECT * FROM temp_union *order_and_group_by_stuff*;
DROP TABLE temp_union;

Note that I've use a HEAP and TEMPORARY table because that combination is rather fast and, well, temporary.
You can't execute these query's on one line (well I coudn't), so it would look like this in PHP:
mysql_query('CREATE..', $connection);
mysql_query('INSERT..', $connection);
$query = mysql_query('SELECT..', $connection);
mysql_query('DROP..', $connection);

Regeren is vooruitschuiven


Verwijderd

Topicstarter
Dat had ik gelezen, echter ik ben niet zo'n voorstander van temporary tables.

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 09:53
Verwijderd schreef op woensdag 27 april 2005 @ 18:21:
Dat had ik gelezen, echter ik ben niet zo'n voorstander van temporary tables.
Dat kan natuurlijk, maar ik vrees dat er weinig akternatief is. Als het simpeler had gekund hadden de MySQL developpers UNION support vast al ingebouwd gehad in versie 3 :)

Een alternatief is om meerdere selects uit te voeren en deze in PHP samen te voegen. Dat lijkt me alleen ranziger dan een temp-table. Qua performance lijkt het me ook niet denderend

Regeren is vooruitschuiven


Verwijderd

Topicstarter
Ik denk dat ik het maar met 2 queries oplos. Dan voeg ik de 2 resultaten samen in een array en sorteer die.

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 07-05 20:19

MBV

Kan je een idee geven wat je met die UNION wil doen? Soms kan je een query herschrijven zodat je een UNION niet nodig hebt.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Verwijderd schreef op woensdag 27 april 2005 @ 18:21:
Dat had ik gelezen, echter ik ben niet zo'n voorstander van temporary tables.
Als je zoiets al gelezen hebt, kun je dat de volgende keer dan in je topicstart vermelden? Dat bespaart weer wat overbodige posts in je topic. :)
Verwijderd schreef op woensdag 27 april 2005 @ 20:13:
Ik denk dat ik het maar met 2 queries oplos. Dan voeg ik de 2 resultaten samen in een array en sorteer die.
Waarom twee queries? Zoals T-MOB al zegt is het in verband met performance zeer waarschijnlijk een stuk beter om een temptable te gebruiken. (Ik zeg zeer waarschijnlijk omdat ik het niet gebenchmarkt heb. Als iemand daar behoefte aan heeft, dan zie ik het hier wel voorbij komen. :+)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 09:53
Ik hoor benchmarks? Iig op mijn server maakt het aantal records nogal wat uit.. met 2 tabellen met een gelijk aantal records is tot +/- 115 records per tabel een oplossing met losse queries sneller. Daarboven wint de temptable. Benchresults:
code:
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 records per tabel:
0.00241613388062s for 2 queries and sort
0.00571203231812s for temptable
ratio ( 2 queries / temptables ): 0.422990232908

** 100 records per tabel:
0.0110280513763s for 2 queries and sort
0.0123798847198s for temptable
ratio ( 2 queries / temptables ): 0.890804044295

** 200 records per tabel:
0.0290281772614s for 2 queries and sort
0.0214860439301s for temptable
ratio ( 2 queries / temptables ): 1.35102475616

** 1000 records per tabel:
0.198834180832s for 2 queries and sort
0.0937490463257s for temptable
ratio ( 2 queries / temptables ): 2.12091950398

** 5000 records per tabel:
1.18799710274s for 2 queries and sort
0.4674680233s for temptable
ratio ( 2 queries / temptables ): 2.54134409954


De code voor het gebruikte script is hier te vinden

Regeren is vooruitschuiven


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 04-05 14:55

Janoz

Moderator Devschuur®

!litemod

De vergelijking is niet helemaal eerlijk. Het sorteren binnen php kan veel sneller wanneer je al beschikt over twee gesorteerde lijsten (wat simpel middels een order by te doen is). Hiervoor gebruik je het laatste stapje van het mergsort algoritme. Je kunt dan zelfs tijdens het afdrukken de gegevens nog 'sorteren' waardoor er nauwelijks verlies optreed.

--edit--
Even uit de losse pols het eerste stukje herschreven. Kunnen legio parse fouten inzitten, maar het geeft je vast een idee:
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
$q1 = mysql_query('SELECT string FROM test1 WHERE tstid > 37 ORDER BY string', $db);
if (mysql_num_rows($q1) > 0) {
    while ($result = mysql_fetch_assoc($q1)) {
        $out1[] = $result['string'];
    }
}
$position1 = 0;
$length1 = $out1.length;
$q2 = mysql_query('SELECT string FROM test2 WHERE tstid > 37 ORDER BY string', $db);
if (mysql_num_rows($q2) > 0) {
    while ($result = mysql_fetch_assoc($q2)) {
        //Eerst alle kleinere elementen in de lijst gooien
        while (($position1 < $lenth1) and ($out1[$position1] < $result['string'])){
            $out[] = $out1[$position1];
            $position1++;
        }
        //Het reultaat van de 2e query toevoegen
        $out[] = $result['string'];
    }
}
//Overgebleven elementen query1 toevoegen
for ($i=$position1;$i<$length1;$i++){
    $out[]=$out1[$i];
}

[ Voor 59% gewijzigd door Janoz op 28-04-2005 08:49 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1