Records uit tabel ordenen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Liefhebber Laravel

Liefhebber Laravel

30/08/2017 11:35:58
Quote Anchor link
Hoi,

Ik heb volgende tabel in mijn databank:

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


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)
PHP script in nieuw venster Selecteer het PHP script
1
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


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.
 
PHP hulp

PHP hulp

04/08/2020 22:08:40
 
Ivo P

Ivo P

30/08/2017 12:04:24
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
SELECT id, parid, value
FROM tabel
ORDER BY parid ASC, id ASC


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
 
Liefhebber Laravel

Liefhebber Laravel

30/08/2017 12:46:49
Quote Anchor link
@Ivo P: Betreffende de parid 0 heb je helemaal gelijk. Dit zou inderdaad NULL moeten zijn. Maar als ik dit aanpas, krijg ik nog steeds dezelfde foute ordening:

originele data:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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


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?
 
Ward van der Put
Moderator

Ward van der Put

31/08/2017 09:29:40
Quote Anchor link
Nu parid NULL mag zijn, kun je sorteren met IFNULL():

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
  SELECT *
    FROM tabel
ORDER BY IFNULL(parid, id)


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.
 
Liefhebber Laravel

Liefhebber Laravel

31/08/2017 10:56:24
Quote Anchor link
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?
 
Ben van Velzen

Ben van Velzen

31/08/2017 11:25:13
Quote Anchor link
Dat is een recursieve functie. Eventueel op te lossen met een stored procedure of stored function, of een functie in PHP.
 
Ivo P

Ivo P

31/08/2017 11:33:37
Quote Anchor link
hoe werkt dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
SELECT *
FROM tabel
ORDER BY COALESCE(parid, id) ASC


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.
 
Liefhebber Laravel

Liefhebber Laravel

31/08/2017 11:56:31
Quote Anchor link
Maar met de COALESCE functie komt mijn record 7 nog steeds niet onder record 5 waarvan het 'child' is
 
Ivo P

Ivo P

31/08/2017 12:57:30
Quote Anchor link
ah het zijn meerdere levels.
had ik overheen gelezen
 
Jan Koehoorn

Jan Koehoorn

31/08/2017 21:15:13
Quote Anchor link
Voorbeeldje met een "harde" 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
<?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);
?>
Gewijzigd op 31/08/2017 21:16:17 door Jan Koehoorn
 
Liefhebber Laravel

Liefhebber Laravel

01/09/2017 14:53:27
Quote Anchor link
Hi Jan, bedankt voor je reactie! Ik heb een oplossing gevonden!

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)
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
// 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);
 



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.