Records uit tabel ordenen
Ik heb volgende tabel in mijn databank:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
id parid value
1 0 value 1
2 0 value 2
3 1 sub of 1
4 1 sub of 1
5 2 sub of 2
6 2 sub of 2
7 5 sub of 5
1 0 value 1
2 0 value 2
3 1 sub of 1
4 1 sub of 1
5 2 sub of 2
6 2 sub of 2
7 5 sub of 5
parid is de parent_id en verwijst naar het id in dezelfde tabel
De bedoeling is dat deze herordend kan worden naar deze volgorde:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
1 0 value 1
3 1 sub of 1
4 1 sub of 1
2 0 value 2
5 2 sub of 2
7 5 sub of 5
6 2 sub of 2
3 1 sub of 1
4 1 sub of 1
2 0 value 2
5 2 sub of 2
7 5 sub of 5
6 2 sub of 2
Zoals je ziet moeten de parent id's onder de gekoppelde id's komen. (record 1 heeft 2 sub id's, namelijk records 3 en 4, dus die moeten onder die record 1 komen)
Kan ik deze ordening toegepast krijgen in MySQL? Of is het beter te doen in PHP?
Ik werk in Laravel, dus mijn databank data kan als collection behandeld worden.
Ter info, de diepte van de subs kan eindeloos zijn.
Toevoeging op 30/08/2017 12:07:04:
ik denk trouwens dat parid nooit 0 zou mogen zijn, aangezien er geen record is met id=0.
Daar zou NULL op zijn plaats zijn.
Daar gaat mijn antwoord ook de mist in: die records met 0 in parid komen bovenaan
originele data:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
id parid value
1 NULL value 1
2 NULL value 2
3 1 sub of 1
4 1 sub of 1
5 2 sub of 2
6 2 sub of 2
7 5 sub of 5
1 NULL value 1
2 NULL value 2
3 1 sub of 1
4 1 sub of 1
5 2 sub of 2
6 2 sub of 2
7 5 sub of 5
Resultaat na de query is hetzelfde...
Toevoeging op 31/08/2017 08:55:50:
Iemand een idee alsjeblieft? Misschien bestaat de mogelijkheid om de resultaten als array te bewerken in PHP om zo het gewenste resultaat te bereiken?
Als parid niet NULL is, dan wordt er gesorteerd op de parid; als parid wél NULL is, dan wordt er gesorteerd op de id.
Dank u Ward, Maar dit werkt enkel voor de eerste diepte, namelijk alle subs onder de hoofd categorie. Maar extra subs worden niet correct geordend. Bestaat daar ook een oplossing voor?
Dat is een recursieve functie. Eventueel op te lossen met een stored procedure of stored function, of een functie in PHP.
COALESCE pakt de eerste waarde uit de lijst (parid, id) die niet gelijk is aan null.
Voor de hoofditems pakt hij dus ID om op te sorteren.
Maar met de COALESCE functie komt mijn record 7 nog steeds niet onder record 5 waarvan het 'child' is
had ik overheen gelezen
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
<?php
$tree = [
['id' => 1, 'parid' => 0, 'value' => 'value 1'],
['id' => 2, 'parid' => 0, 'value' => 'value 2'],
['id' => 3, 'parid' => 1, 'value' => 'sub of 1'],
['id' => 4, 'parid' => 1, 'value' => 'sub of 1'],
['id' => 5, 'parid' => 2, 'value' => 'sub of 2'],
['id' => 6, 'parid' => 2, 'value' => 'sub of 2'],
['id' => 7, 'parid' => 5, 'value' => 'sub of 5'],
['id' => 8, 'parid' => 5, 'value' => 'sub of 5'],
['id' => 9, 'parid' => 5, 'value' => 'sub of 5'],
];
function printTree($parid = 0, $tree)
{
foreach ($tree as $node) {
if ($node['parid'] === $parid) {
vprintf('node id: %d, parent id: %d, $value: %s' . PHP_EOL, $node);
printTree($node['id'], $tree);
}
}
return;
}
printTree(0, $tree);
?>
$tree = [
['id' => 1, 'parid' => 0, 'value' => 'value 1'],
['id' => 2, 'parid' => 0, 'value' => 'value 2'],
['id' => 3, 'parid' => 1, 'value' => 'sub of 1'],
['id' => 4, 'parid' => 1, 'value' => 'sub of 1'],
['id' => 5, 'parid' => 2, 'value' => 'sub of 2'],
['id' => 6, 'parid' => 2, 'value' => 'sub of 2'],
['id' => 7, 'parid' => 5, 'value' => 'sub of 5'],
['id' => 8, 'parid' => 5, 'value' => 'sub of 5'],
['id' => 9, 'parid' => 5, 'value' => 'sub of 5'],
];
function printTree($parid = 0, $tree)
{
foreach ($tree as $node) {
if ($node['parid'] === $parid) {
vprintf('node id: %d, parent id: %d, $value: %s' . PHP_EOL, $node);
printTree($node['id'], $tree);
}
}
return;
}
printTree(0, $tree);
?>
Gewijzigd op 31/08/2017 21:16:17 door Jan Koehoorn
Ik haal alle records uit de tabel (SELECT * FROM tabel ORDER BY id), vervolgens haal ik die array door jouw functie en bouw ik zo een nieuwe, correct geordende array.
Ik werk in Laravel, en laravel gebruikt collecties, dus moest ik de functie even aanpassen: hier mijn oplossing:
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
// Alle rijen binnenhalen
$records = App\Record::->all();
$ids = array();
$teller = 0;
function setorder($parid = 0, $tree){
global $ids;
global $teller;
foreach ($tree as $node) {
if ($node->main_group_id === $parid) {
// nieuwe array $ids aanvullen met gegevens
$ids[$teller]['id'] = $node->id;
$ids[$teller]['level'] = $node->level;
$ids[$teller]['final'] = $node->final;
$teller++;
setorder($node->id, $tree);
}
}
return $ids;
}
$d = setorder(0, $specs);
// array omzetten naar collectie
$d = collect($d);
dd($d);
$records = App\Record::->all();
$ids = array();
$teller = 0;
function setorder($parid = 0, $tree){
global $ids;
global $teller;
foreach ($tree as $node) {
if ($node->main_group_id === $parid) {
// nieuwe array $ids aanvullen met gegevens
$ids[$teller]['id'] = $node->id;
$ids[$teller]['level'] = $node->level;
$ids[$teller]['final'] = $node->final;
$teller++;
setorder($node->id, $tree);
}
}
return $ids;
}
$d = setorder(0, $specs);
// array omzetten naar collectie
$d = collect($d);
dd($d);