Jump to content
php.lv forumi

Menu tree The Nested Set Model


mysql_query
 Share

Recommended Posts

Ir sekojošs query:

 

SELECT CONCAT( 15 *(COUNT(parent.id) - 1),'') AS spacer

FROM

menu AS node,

menu AS parent

WHERE node.lft BETWEEN parent.lft AND parent.rgt

GROUP BY node.id

ORDER BY node.lft //// vai pēc secības node.seciba

LIMIT $pg, $limits

 

1. Visu bezgalīgo menu tree izvada kā vajag, ir ok.

2 LIMITs darbojas kā vajag, ir ok.

BET

3. Nevaru veikt ORDERu pēc secības, ja veicu tad menu tree sajaucas. Katram menu līmeni ir sava secība.

 

Piem: ORDER BY node.lft

 

nosakums | seciba |

aa |1

--aa |1

--bb |2

 

zz |2

--cc |1

--dd |2

 

Piem: ORDER BY node.seciba

 

nosakums | seciba |

aa |1

zz |2

--aa |1

--cc |1

--bb |2

--dd |2

 

Kāds varētu būt risinājums.

 

 

Menu tree ideja ir smelta no

http://dev.mysql.com/tech-resources/articles/hierarchical-data.html | The Nested Set Model

Link to comment
Share on other sites

Tāda administrācija pusē ievada menu un sub sub menu.

 

ORDER BY node.lft

 

nosaukums | seciba

 

aa | 1

--a1 |1

--a2 |2

----aa1 |1

----aa2 |2

 

bb | 2

--bb |1

--bb2|2

 

 

Ir nepieciešam lai menu saglabā savu hirarhiju arī pēc - ORDER BY node.seciba

Ja būs ORDER BY node.seciba menu hirarhijā būs sajaukta vietām.

 

Tātad jautājums, Kā lai saglabā menu hirarhiju arī pēc ORDER BY node.seciba ?

Edited by mysql_query
Link to comment
Share on other sites

Kas ir seciba? Kaut kāds kārtas numurs augšējā līmeņa ietvaros? Tajā modelī nekā tāda nav.

Klau Tu varētu:

1kārt, ja Tavu tabulu struktūra atšķiras no tā, kas dots oriģinālajā rakstā, tad iedot create table teikumus + insertus tiem dažiem datiem

2kārt precīzi formulēt to, kas sanāk un to ko vajag. Piemēram, lūk šādi:

Šobrīd varu dabūt šādi:

mysql> SELECT node.category_id id,
   ->   CONCAT( REPEAT(' ', COUNT(parent.name) - 1), node.name) AS name
   -> FROM nested_category AS node,
   -> nested_category AS parent
   -> WHERE node.lft BETWEEN parent.lft AND parent.rgt
   -> GROUP BY node.name
   -> ORDER BY node.lft;
+----+-----------------------+
| id | name                  |
+----+-----------------------+
|  1 | ELECTRONICS           |
|  2 |  TELEVISIONS          |
|  3 |   TUBE                |
|  4 |   LCD                 |
|  5 |   PLASMA              |
|  6 |  PORTABLE ELECTRONICS |
|  7 |   MP3 PLAYERS         |
|  8 |    FLASH              |
|  9 |   CD PLAYERS          |
| 10 |   2 WAY RADIOS        |
+----+-----------------------+
10 rows in set (0.00 sec)

 

Vajag lai būtu:

+----+-----------------------+
| id | name                  |
+----+-----------------------+
|  1 | ELECTRONICS           |
|  6 |  PORTABLE ELECTRONICS |
| 10 |   2 WAY RADIOS        |
|  9 |   CD PLAYERS          |
|  7 |   MP3 PLAYERS         |
|  8 |    FLASH              |
|  2 |  TELEVISIONS          |
|  4 |   LCD                 |
|  5 |   PLASMA              |
|  3 |   TUBE                |
+----+-----------------------+

Kur visas apakškategorijas ir sakārtotas alfabētiski virskategorijas ietvaros.

 

P.S. Nav ne jausmas kā var dabūt 2ro variantu, bet gan jau ka var :)

 

Gints Plivna

http://datubazes.wordpress.com

Link to comment
Share on other sites

Jā tieši tā,

2 variants. Pieņemsim ka man vajag sakārtot visu alfabētiskā secībā pēc nosaukuma.

 

Es otro variantu nevaru tikt gālā jau otro dienu.

 

Domāju ka izmantošu recursive - variantu. Bet te man būs jātierk galā ar LIMIT, vēl nesmu iedziļinājies par limit risinājumu bet domāju kas tas arī varētu būt sāpīgs jautājums.

Link to comment
Share on other sites

Kā šajama var pielikt LIMIT

 

<?php
  function show_menu($id) {
          $all = mysql_query("SELECT * FROM main Where parent_id=$id ORDER BY id ASC");
          if (!$all) { echo( mysql_error()); } else {
                  if (mysql_num_rows($all) {
                          echo '<ul class="id_nav">';
                          while ($row = mysql_fetch_array($all)) {
                                  echo '<li><a class="nav" href="?id='.$row['id'].'">'.$row['name'].'</a>';
                                  show_menu($row['id']);
                                  echo '</li>';
                          }
                          echo '</ul>';
                  }
          }
  }
  show_menu(0);
?>

 

1. Man ir piem 300 menu kopā.

2. Iespējams daži ir kā sub, sub sub menu .

3. tad kā lai sadalu pa lapām? Un lai herahija tupinātos nākamjā lapā.

Link to comment
Share on other sites

Jā tieši tā,

2 variants. Pieņemsim ka man vajag sakārtot visu alfabētiskā secībā pēc nosaukuma.

 

Nu par 90% ir:

mysql> SELECT node.name, node.category_id
   -> FROM nested_category AS node,
   -> nested_category AS parent
   -> WHERE node.lft BETWEEN parent.lft AND parent.rgt
   -> group by node.name
   -> order by group_concat(parent.name ORDER BY parent.lft);
+----------------------+-------------+
| name                 | category_id |
+----------------------+-------------+
| ELECTRONICS          |           1 |
| PORTABLE ELECTRONICS |           6 |
| 2 WAY RADIOS         |          10 |
| CD PLAYERS           |           9 |
| MP3 PLAYERS          |           7 |
| FLASH                |           8 |
| TELEVISIONS          |           2 |
| LCD                  |           4 |
| PLASMA               |           5 |
| TUBE                 |           3 |
+----------------------+-------------+
10 rows in set (0.00 sec)

 

Uzlabots variants

 

Gints Plivna

http://datubazes.wordpress.com

Edited by Gints Plivna
Link to comment
Share on other sites

Gala risinājums - bezgalīgam menu tree.

 

function get_path($start) {
$pathArray = array();
$query = mysql_query("SELECT * FROM menu WHERE parent='$start' ");
 while ($row = mysql_fetch_array($query)) {
   $pathArray[] = $row;
   $pathArray = array_merge($pathArray, get_path($row['id']));
 }
return $pathArray;
}

Link to comment
Share on other sites

Nu par 90% ir:

mysql> SELECT node.name, node.category_id
   -> FROM nested_category AS node,
   -> nested_category AS parent
   -> WHERE node.lft BETWEEN parent.lft AND parent.rgt
   -> group by node.name
   -> order by group_concat(parent.name ORDER BY parent.lft);
+----------------------+-------------+
| name                 | category_id |
+----------------------+-------------+
| ELECTRONICS          |           1 |
| PORTABLE ELECTRONICS |           6 |
| 2 WAY RADIOS         |          10 |
| CD PLAYERS           |           9 |
| MP3 PLAYERS          |           7 |
| FLASH                |           8 |
| TELEVISIONS          |           2 |
| LCD                  |           4 |
| PLASMA               |           5 |
| TUBE                 |           3 |
+----------------------+-------------+
10 rows in set (0.00 sec)

 

Uzlabots variants

 

Gints Plivna

http://datubazes.wordpress.com

 

 

Šis risinājums nestrādā.

Link to comment
Share on other sites

Šis risinājums nestrādā.

Kas tieši nestrādā? Kā tas izpaužās? Atkal jāuzdod kāds bariņš ar precizējošiem jautājumiem, lai kaut ko saprastu? ;)

 

Gints Plivna

http://datubazes.wordpress.com

 

 

P.S. OK anyway, cik saprotu, tad esi atradis savu risinājumu un, ja tas strādā, tad, protams, nav vērts rakt paralēlā virzienā.

Edited by Gints Plivna
Link to comment
Share on other sites

Es pārbaudīju Ginta variantu ar group_concat un viss tur strādā. Man tāda lieta arī ir mazliet aktuāla. Vienīgi nepatīk ka group_concat ir ierobežojums, kas dažreiz varēs izpausties pie konstrukcijām ar ļoti lielu dziļumu. To protams var labot ar MySql group_concat_max_len mainīgā palīdzību, bet jebkurā gadījumā nevar zināt cik dziļi koks tiks sataisīts sistēmas izmantošanas laikā, jo tādi modeļi paredz tieši neierobežotu dziļumu.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...