Tabellen samenvoegen uit meerdere MySQL databases op dezelfde server

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Brecht S

Brecht S

27/08/2016 12:46:48
Quote Anchor link
Ik ben aan het proberen om de nieuwsitems uit 2 verschillende databases te halen. De inloggegevens bij beide databases is verschillend maar de tabel naam is bij beide dezelfde, en dat is 'blog'.
Ik kan ook niet echt werken met een join omdat ik alle gegevens uit beide tabellen nodig heb en er geen voorwaarden zijn buiten dat het op datum moet gesorteerd zijn (desc) en gelimiteerd zijn tot 5 items. Dus kort gezegd komt dit neer op 'geef mij in de select alle resultaten uit beide databases in tabel 'blog' gesorteerd op datum en enkel de laatste 5'

Verder heb ik geen idee hoe ik hieraan moet beginnen.

Ik kan gegevens uit beide tabellen halen maar niet samen.
Heeft iemand een voorbeeld?
 
PHP hulp

PHP hulp

06/11/2024 00:13:38
 
Jan Koehoorn

Jan Koehoorn

27/08/2016 12:57:54
Quote Anchor link
Uit mijn hoofd:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(
SELECT col1, col2, col3
FROM db1.blog
ORDER BY datetime DESC
LIMIT 5
)

UNION

(
SELECT col1, col2, col3
FROM db2.blog
ORDER BY datetime DESC
LIMIT 5
)
 
Brecht S

Brecht S

27/08/2016 14:20:26
Quote Anchor link
Dat heb ik al eens geprobeerd maar eerst maak ik een connectie met de databases en zou het kunnen dat het daar fout gaat? Idividueel werkt dat wel maar niet samen precies.

Connectie maak ik op deze manier:
filename: config-1.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
$host = "localhost";
$user = "xxx"; // gebruikersnaam van je phpMyAdmin.
$pass = "xxxx"; // wachtwoord van je phpMyAdmin.
$dbnm = "xxxxx";


filename: config-2.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
$host = "localhost";
$user = "xxx"; // gebruikersnaam van je phpMyAdmin.
$pass = "xxxx"; // wachtwoord van je phpMyAdmin.
$dbnm = "xxxxx";


Dan ga ik die met een require_once('config-1.php') en require_once('config-2.php') gaan inladen. En daarna:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
require_once ('connections/config-1.php');
require_once ('connections/config-2.php');
          
         $conn9 = mysql_connect($host,$user,$pass) or die (mysql_error());
         mysql_select_db($dbnm) or die (mysql_error());
        
         $sql = "
         (
SELECT titel
FROM euro_leadmap.blog
ORDER BY datum DESC
LIMIT 5
)

UNION

(
SELECT titel
FROM security_leadmap.blog
ORDER BY datum DESC
LIMIT 5
)
";
         $res = mysql_query($sql) or die (mysql_error());


Maar dan gaat het precies fout en krijg ik een foutmelding.
Error: SELECT command denied to user 'security_leadmap'@'localhost' for table 'blog'

Ik weet dat het nog de oude connectie methode is maar pas die later wel aan naar een mysqli connectie of PDO.
Gewijzigd op 27/08/2016 14:34:40 door Brecht S
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/08/2016 14:57:17
Quote Anchor link
>> De inloggegevens bij beide databases is verschillend

Volgens mij zul je het dan in PHP moeten oplossen.

stap 1: 5 laatste items ophalen uit db 1

stap 2: 5 laatste items ophalen uit db 2

(Je hebt nu twee arrays met records. Zorg dat de kolomnamen gelijk zijn en zeker de datum kolomnamen)

stap 3: voeg de twee arrays samen met array_merge().

stap 4: Sorteer de array met een eigen vergelijking-functie

stap 5: Verwijder de laatste 5 items van de array

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

function compareDates($a, $b)
{

    // omzetten van tekst naar timestamp
    $a = strtotime($a['created']);
    $b = strtotime($b['created']);
    
    if ($a == $b) {
        return 0;
    }

    return ($a > $b) ? -1 : 1;
}


// hoeveel records wil je overhouden?
$limit = 5;

// dit is zogenaamd het resultaat van twee mysql queries
$rows1 = array(
    array('created' => '2016-08-21', 'body' => 'Nieuws 1 van database 1'),
    array('created' => '2016-08-19', 'body' => 'Nieuws 2 van database 1'),
    array('created' => '2016-08-17', 'body' => 'Nieuws 3 van database 1'),
    array('created' => '2016-08-15', 'body' => 'Nieuws 4 van database 1'),
    array('created' => '2016-08-13', 'body' => 'Nieuws 5 van database 1'),
);


$rows2 = array(
    array('created' => '2016-08-20', 'body' => 'Nieuws 1 van database 2'),
    array('created' => '2016-08-18', 'body' => 'Nieuws 2 van database 2'),
    array('created' => '2016-08-16', 'body' => 'Nieuws 3 van database 2'),
    array('created' => '2016-08-14', 'body' => 'Nieuws 4 van database 2'),
    array('created' => '2016-08-12', 'body' => 'Nieuws 5 van database 2'),
);

    
// arrays samenvoegen
$rows = array_merge($rows1, $rows2);

// array sorteren op datum
usort($rows, 'compareDates');

// de laatste vijf items van de array weghalen
$rows = array_slice($rows, 0, $limit);

foreach ($rows as $row) {
    echo $row['created'] . ': ' . $row['body'] . "<br>\n";
}

?>
 
Brecht S

Brecht S

27/08/2016 15:06:13
Quote Anchor link
@Frank: moet ik eens proberen. Een hele boterham... Wist niet dat het zo ingewikkeld was. Moesten de logingegevens van beide databases dezelfde zijn zou het dus eigenlijk veel eenvoudiger zijn? Maar in mijn geval is dat niet mogelijk omdat die van 2 verschillende klanten zijn.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/08/2016 15:12:39
Quote Anchor link
Laat me je helpen Brecht. Laat eens zien hoe je de rijen ophaalt uit de database dan pas ik het voorbeeld aan op jouw situatie.
 
Brecht S

Brecht S

27/08/2016 15:29:04
Quote Anchor link
Kan je mij wel beetje helpen hoe ik dit voor elkaar krijg vanuit mijn select query?

// dit is zogenaamd het resultaat van twee mysql queries
$rows1 = array(
array('created' => '2016-08-21', 'body' => 'Nieuws 1 van database 1'),
array('created' => '2016-08-19', 'body' => 'Nieuws 2 van database 1'),
array('created' => '2016-08-17', 'body' => 'Nieuws 3 van database 1'),
array('created' => '2016-08-15', 'body' => 'Nieuws 4 van database 1'),
array('created' => '2016-08-13', 'body' => 'Nieuws 5 van database 1'),
);

$rows2 = array(
array('created' => '2016-08-20', 'body' => 'Nieuws 1 van database 2'),
array('created' => '2016-08-18', 'body' => 'Nieuws 2 van database 2'),
array('created' => '2016-08-16', 'body' => 'Nieuws 3 van database 2'),
array('created' => '2016-08-14', 'body' => 'Nieuws 4 van database 2'),
array('created' => '2016-08-12', 'body' => 'Nieuws 5 van database 2'),
);

Toevoeging op 27/08/2016 15:30:25:

Dit was tot nu toe mijn query om te proberen maar ik krijg een andere opgebouwde array:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
require_once ('connections/config-euroblok.php');

         $conn9 = mysql_connect($host,$user,$pass) or die (mysql_error());
         mysql_select_db($dbnm) or die (mysql_error());
        
         $sql = "SELECT * FROM blog WHERE actief = 'ja' ORDER BY datum desc LIMIT 4";
         $res = mysql_query($sql) or die (mysql_error());
        
        
while ($row = mysql_fetch_array($res))
{

    $new_array[$row['datum']]['titel'] = $row['titel'];
    $new_array[$row['datum']]['datum'] = $row['datum'];
}


         echo '<pre>';
         print_r($new_array);
        
         mysql_close($conn9);
                         
?>


Toevoeging op 27/08/2016 15:32:18:

Dit is het resultaat van bovenstaande:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
Array
(
    [2016-08-17] => Array
        (
            [titel] => Veiligheidsdeuren: De beste inbraakpreventie
            [datum] => 2016-08-17
        )

    [2016-07-05] => Array
        (
            [titel] => Met deze tools vertrek je veilig op reis
            [datum] => 2016-07-05
        )

    [2016-06-28] => Array
        (
            [titel] => Hoe beveilig ik mijn kantoor?
            [datum] => 2016-06-28
        )

    [2016-06-20] => Array
        (
            [titel] => Uw veiligheidsdeur opmeten: Hoe doen we dat?
            [datum] => 2016-06-20
        )

)
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/08/2016 15:51:30
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

function compareDates($a, $b)
{

    // omzetten van tekst naar timestamp
    $a = strtotime($a['datum']);
    $b = strtotime($b['datum']);
    
    if ($a == $b) {
        return 0;
    }

    return ($a > $b) ? -1 : 1;
}


// hoeveel records wil je overhouden?
$limit = 5;

require_once ('connections/config-1.php');
$conn1 = mysql_connect($host ,$user,  $pass) or die (mysql_error());
mysql_select_db($dbnm, $conn1) or die (mysql_error());
$result = mysql_query('SELECT datum, titel FROM euro_leadmap.blog ORDER BY datum DESC LIMIT ' . $limit, $conn1) or die (mysql_error());
while($row = mysql_fetch_assoc($result)) {
    $rows1[] = $row
}

require_once ('connections/config-2.php');
$conn2 = mysql_connect($host ,$user,  $pass) or die (mysql_error());
mysql_select_db($dbnm, $conn2) or die (mysql_error());
$result = mysql_query('SELECT datum, titel FROM security_leadmap.blog ORDER BY datum DESC LIMIT ' . $limit, $conn2) or die (mysql_error());
while($row = mysql_fetch_assoc($result)) {
    $rows2[] = $row;
}

    
// arrays samenvoegen
$rows = array_merge($rows1, $rows2);

// array sorteren op datum
usort($rows, 'compareDates');

// de laatste vijf records van de array weghalen
$rows = array_slice($rows, 0, $limit);

foreach ($rows as $row) {
    echo $row['datum'] . ': ' . $row['titel'] . "<br>\n";
}

?>
Gewijzigd op 27/08/2016 17:32:20 door Frank Nietbelangrijk
 
Brecht S

Brecht S

27/08/2016 16:31:47
Quote Anchor link
Ik krijg een lege pagina. Er zit ergens een fout in... Kan ze niet direct vinden. De $rows1 en $rows2 kan ik wel apart oproepen (de array's dan), dus daar zit het niet.

Toevoeging op 27/08/2016 16:33:24:

Waarom doe jij in deze query $result = mysql_query('SELECT datum, titel FROM euro_leadmap.blog ORDER BY datum DESC LIMIT ' . $limit, $conn1) $limit, $conn1?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/08/2016 17:28:39
Quote Anchor link
>> Waarom doe jij in deze query $result = mysql_query('SELECT datum, titel FROM euro_leadmap.blog ORDER BY datum DESC LIMIT ' . $limit, $conn1) $limit, $conn1?

  • Het eerste voorbeeld is getest en werkt
  • Het laatste voorbeeld kon ik niet testen
  • Ik heb de query overgenomen van jouw post alleen heb ik ook de DATUM laten selecteren omdat we die nodig hebben om later binnen PHP wederom de rijen op datum te kunnen sorteren
  • Ik geef ook de tweede parameter mee aan de mysql_seelct_db() en de mysql_query() functie omdat je met twee verschillende database connecties werkt.
  • Hou je er rekening mee dat als je twee configuratie bestanden included en er staan dezelfde variabelen in dat de tweede include de variabelen van de eerste include overschrijft?
  • Hou je er rekening mee dat mysql_* functies niet meer werken in PHP7?


Toevoeging op 27/08/2016 17:31:20:

Ah ik merk nu nog een typo. Ik zal het even aanpassen
Ik heb het laatste voorbeeld gewijzigd (regel 23 en 31). Probeer het nog maar eens
Gewijzigd op 27/08/2016 17:34:42 door Frank Nietbelangrijk
 
Brecht S

Brecht S

27/08/2016 21:12:14
Quote Anchor link
Ja inderdaad dat had ik daarnet ook gezien. Was inderdaad de fout. Ondertussen je code al een beetje uitgebreid en werkt perfect.
Nog een vraagje. Is het mogelijk om in de eerste query en in de tweede query iets mee te geven dat ik weet van welke bron het komt? Bvb de eerste query komt van firma A en de tweede query komt van firma B maar die gegevens zitten niet in een van de velden in mijn tabel. Dus zou die ergens fictief moeten kunnen zetten.

Toevoeging op 27/08/2016 21:13:28:

En ja, ik weet dat de query niet meer zal werken in een PHP7 omgeving, daarom moet ik nu nog alles omzetten naar mysqli of PDO class. Maar probeer eerst even met het 'oude vertrouwde'...
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/08/2016 21:18:38
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
SELECT *, 'google' AS bedrijfsnaam FROM tabelnaam
 
Brecht S

Brecht S

27/08/2016 22:29:29
Quote Anchor link
Ok, dat werkt. Maar nu komt het volgende probleem naar boven.

Ik heb een blok met 2 items in volgens de hierboven opbouw.

Nu wil ik daaronder een blok met 3 items naast elkaar, daarom kopieer ik die code en pas in de 2 queries aan dat de LIMIT 3 OFFSET 2 moet zijn (bij beide queries). Zo krijg ik niet dezelfde items als die in de blok erboven.
Hier gaat het fout want ik krijg dubbele items en blijkbaar enkel maar uit 1 database.

Resultaat van mijn laatste 2 queries:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
2015-11-05 => Checklist voor een veilige parking => Foto => parking-slagbomen-tips.jpg
2015-11-05 => Checklist voor een veilige parking => Foto => parking-slagbomen-tips.jpg
2015-10-12 => Camerabewaking = uw klanten een veilig gevoel geven => Foto => camerabewaking-resize.jpg
2015-10-12 => Parkingbeheer: 5 tips voor het inrichten van uw nieuwe parking => Foto => toegangscontrole.jpg
2015-10-12 => Camerabewaking = uw klanten een veilig gevoel geven => Foto => camerabewaking-resize.jpg


Dit hierboven zijn resultaten (met dubbels) uit mijn 2de query en van mijn eerste mixt hij die er niet meer doorheen.
Enig idee hoe dit kan komen?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/08/2016 22:47:13
Quote Anchor link
als de tweede vijf nieuwsberichten heeft die alle vijf nieuwer zijn dan de nieuwste van de eerste dan laat hij die zien.

Of zijn de datum-types verschillend in de database?
 
Brecht S

Brecht S

27/08/2016 22:48:16
Quote Anchor link
Als ik de beide queries apart probeer met een print_r krijg ik telkens dezelfde resultaten terug en deze altijd van de 2de query, ook al is met de eerste een connectie gemaakt.
Het gaat hier over dezelfde databases (met dezelfde datum-notaties) alleen moeten de resultaten hier anders zijn. Met die limit 3 OFFSET 2 wil ik eigenlijk 3 items weergeven maar startende vanaf het 3de item. Op die manier probeer ik niet dezelfde gegevens te verkrijgen als in de eerste blok met 2 items.

Toevoeging op 27/08/2016 23:00:15:

Voor alle duidelijkheid is mijn opbouw zo:

Blok met 2 items (mix van 2 databases)

Daaronder:

Blok met 3 items (terug een mix van dezelfde 2 databases)

Bij de eerste blok met 2 items heb ik jouw code gebruikt met enkele aanpassingen en daar gaat volgens mij alles goed.
Ik herhaal dezelfde code voor blok 2 (met de 3 items) en dan lukt het niet meer.
Ik gebruik de print_r voor de eerste query results te zien en een print_r om de tweede query results te zien, maar beiden zijn dus identiek aan elkaar, vandaar de dubbels in mijn eindresultaat.
Waarom krijg ik de results van de 2de query als ik de eerste aanroep?
Gewijzigd op 27/08/2016 22:51:29 door Brecht S
 
Brecht S

Brecht S

29/08/2016 11:14:44
Quote Anchor link
@Frank: kan je mij iets laten weten waar je denkt dat het fout gaat?
Gewijzigd op 29/08/2016 11:15:10 door Brecht S
 
Thomas van den Heuvel

Thomas van den Heuvel

29/08/2016 12:29:10
Quote Anchor link
Kun je niet gewoon in het 2-item-block $rows[0] en $rows[1] afdrukken en in het 3-item-block $rows[2] t/m $rows[4]? Je hebt toch al genoeg resultaten opgehaald (en in de goede volgorde gezet) voor beide blokken? Waarom zou je moeilijke dingen met offsets gaan doen? Dit kun je in PHP regelen. Daar heb je alle informatie al.
 
Brecht S

Brecht S

29/08/2016 12:54:51
Quote Anchor link
Ik heb het gevonden. De fout lag aan het invoeren van 2x dezelfde require_once. Als je dat doet op 1 pagina dan gaat het dus fout.

Nu wel nog een bijkomende vraag. Als je de code van Frank bekijkt hier iets meer naar boven, dan zou ik daar nog een pagination bij willen. Ik weet hoe ik dit moet doen als het in 1 query zit maar niet als de query in een array worden gestoken. Kan iemand mij hiermee helpen?
Gewijzigd op 29/08/2016 13:41:08 door Brecht S
 
Thomas van den Heuvel

Thomas van den Heuvel

29/08/2016 13:43:54
Quote Anchor link
In jouw geval snijdt LIMIT 3,2 geen hout omdat de informatie uit twee databases komt (toch?). Je kunt niet op voorhand zeggen hoeveel resultaten uit database A komen en hoeveel resultaten uit database B. Op voorhand daar een offset aan plakken is dan ook niet zinnig.

Jij (of @Frank) hebt nu net een heleboel moeite gedaan om daar één gesorteerde lijst van te bakken, maak daar dan ook gebruik van :p.

Even voor de duidelijkheid: zit er overlap in blog-items in database A en B, of zijn alle blog-items uniek?

---

EDIT: zou het niet veel handiger zijn als je hier één lijst / blogtabel van maakt, te meer als je met paginering wilt gaan werken. Je hebt hier namelijk hetzelfde probleem: je moet eerst uitrekenen op welke positie (en daarmee welke pagina) dingen staan. Je bent nu op twee benen aan het hinken.
Gewijzigd op 29/08/2016 13:46:05 door Thomas van den Heuvel
 
Brecht S

Brecht S

29/08/2016 14:06:30
Quote Anchor link
Ik doe eerst een query met die LIMIT 3 OFFSET 2 op de ene database en steek de waarden in een array. Daarna doe ik hetzelfde voor de 2de database. Zo blok ik toch mijn resultaten?

De blog-items uit database A zijn niet dezelfde als uit database B. Alleen de velden komen overeen van de tabellen.
Alleen mogen de items die ik eerst weergeef in de 2 blokken in de HTML niet dezelfde zijn als ik weergeef in de 3 blokken daaronder.

Van die paginering heb ik geen idee hoe dit aan te pakken.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.