Tabellen samenvoegen uit meerdere MySQL databases op dezelfde server
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?
Connectie maak ik op deze manier:
filename: config-1.php
Code (php)
1
2
3
4
2
3
4
$host = "localhost";
$user = "xxx"; // gebruikersnaam van je phpMyAdmin.
$pass = "xxxx"; // wachtwoord van je phpMyAdmin.
$dbnm = "xxxxx";
$user = "xxx"; // gebruikersnaam van je phpMyAdmin.
$pass = "xxxx"; // wachtwoord van je phpMyAdmin.
$dbnm = "xxxxx";
filename: config-2.php
Code (php)
1
2
3
4
2
3
4
$host = "localhost";
$user = "xxx"; // gebruikersnaam van je phpMyAdmin.
$pass = "xxxx"; // wachtwoord van je phpMyAdmin.
$dbnm = "xxxxx";
$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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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());
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
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)
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
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";
}
?>
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";
}
?>
@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.
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.
// 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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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);
?>
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)
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
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
)
)
(
[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
)
)
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
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";
}
?>
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
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?
- 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:
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
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'...
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)
1
2
3
4
5
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
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?
Of zijn de datum-types verschillend in de database?
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
Gewijzigd op 29/08/2016 11:15:10 door Brecht S
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.
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
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
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.