You are not logged in.

  • Login

1

Wednesday, November 18th 2009, 4:48pm

Ausgabe von Kategorien und Subkategorien

Hallo, ich brauche mal eure Hilfe.

Ich wollte meine Kategorien und die dazugehörigen Subkategorien ausgeben.

In meiner SQL Tabelle "Kategorien" sind folgende Spalten: ID, Hauptkategorie, Position, Name

Ich will jetzt also alle Kategorien nach der Reiehe ausgeben und nach der Kategorie sofort die Subkategorie.
Dazu lass ich erst mal alle Kategorien die keine hauptkateorie haben ausgeben ( das sind die Hauptkategorien) und dann wollte ich alle ausgeben die eine Hauptkategorie haben und somit die Subkategorien sind.

Source code

1
2
3
4
5
6
<?php while($aus = mysql_fetch_array($sql)){
		 if ($aus['hauptkat'] == "0") { ?>
         <li><a href="?go=kat&kat=<?php echo $aus['id'] ?>"> -> <?php echo $aus['name'] ?> </a></li>
         <?php if ($aus['hauptkat'] > "0") { ?>
         	<li><a href="?go=kat&kat=<?php echo $aus['id'] ?>"> -> <?php echo $aus['name'] ?> </a></li>
		 	<?php } } } // Ende der Schleife ?>



Das Problem ist das er mir nur die Hauptkategorien ausgeben will. Könnt ihr mir helfen ?

habe ich das vom Prinzip her sinnvol gelöst oder ist das totaler quatsch ?

2

Wednesday, November 18th 2009, 6:30pm

Das simpelstre wäre es natürlich mit 2 while Schleifen.
Ich weiss aber nicht ob du es "unsaubar" haben willst und ich hätte jetzt im moment nicht genug Code um dir das zu zeigen.
Ich denke aber, dass du das hinbekommst.

btw, neo99?

3

Wednesday, November 18th 2009, 6:38pm

Ich versteh nicht ganz warum 2 while Schleifen ?

Ich möchte ja die Kategorien so geordnet haben:

1. Kategorie
-> SubKategorie
2. Kategorie
-> SubKategorie

Wenn ich 2 Schleifen habe dann ist es doch so ?

1. Kategorie
2. Kategorie

-> SubKategorie
-> SubKategorie

Ich steh echt aufm Schlauch gerade.

4

Wednesday, November 18th 2009, 6:50pm

hier ein kleines Beispiel

Erste while Schleife ---- $sql = mysql_query("Select * from kategorien where Hauptkategorie = ''");
|
v
Zweite while Schleife ---- $sql = mysql_query("Select * from kategorien where Hauptkategorie != '' and Hauptkategorie = '".$row->id."'");

Ich weiss ja nicht wie die Datenbank aufgebaut ist, aber das sollte sich auf alles ableiten können.

5

Wednesday, November 18th 2009, 8:16pm

Ja thx,

also mit zwei ineinander verschachtelten while schleifen funktioniert es.

Source code

1
2
3
4
5
6
7
8
     	<?php while($aus = mysql_fetch_array($sql)){ ?>
     	<li><a href="?go=kat&kat=<?php echo $aus['id'] ?>"> -> <?php echo $aus['name'] ?> </a></li>
     	<?php
		 $auswahl2 	= "SELECT * FROM *** WHERE haupt*** = ".$****['id']." ORDER BY position ASC";
		 $sql2    	= mysql_query($auswahl2);
		 while($aus2 = mysql_fetch_array($sql2)) { ?>
     		<li><a href="?go=kat&kat=<?php echo $aus2['id'] ?>"> ----> <?php echo $aus2['name'] ?> </a></li>
		 	<?php } }  // Ende der Schleife ?>

6

Wednesday, November 18th 2009, 10:04pm

Hi,
da man niemals Datenbankabfragen in einer Schleife ausführen sollte, würde ich dir empfehlen, dich in der Verwendung von Caches zu üben.
Wenn du objektorientiert programmierst, dann ist es egal ob die Datenquelle eine Datenbank ist, ein Cache oder ein Array.

Außerdem interessante Stichworte sind "Nested Sets"

7

Thursday, November 19th 2009, 8:13am

Hey,

können Subkategorien auch Subkategorien enthalten? Also eine Subsubkategorie?

Und ist das ein komplett eigenes Script oder nur eine Ergänzung? Es währe von Vorteil, die Datenbankstruktur zu kennen... ;)


Gruß,
Nick
Latest blogs Latest blogs: Bloggen...

8

Thursday, November 19th 2009, 12:18pm

Du könntest dein Ziel durch eine Art Workaround erreichen:

SQL Code

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT parent.ID AS p_ID
, parent.Hauptkategorie AS p_Hauptkategorie
, parent.Position AS p_Position
, parent.Name AS p_Name
, child.ID AS c_ID
, child.Hauptkategorie AS c_Hauptkategorie
, child.Position AS c_Position
, child.Name AS c_Name
FROM Kategorien AS parent
LEFT JOIN Kategorien AS child
ON child.Hauptkategorie=parent.ID
WHERE ISNULL(parent.Hauptkategorie)
ORDER BY parent.Position, child.Position;


Die Datensätze, die du erhältst haben dann folgende Form: p_ID, p_Hauptkategorie, p_Position, p_Name, c_ID, c_Hauptkategorie, c_Position, c_Name. Dieser Ansatz hat aber einige Nachteile:

  • die Breite des RS ist hoch, die Daten der Hauptkategorie werden ggf. mehrfach übergeben
  • dieses Prinzip funktioniert nur, wenn du maximal zwei Ebenen hast, es also keine Unterunterkategorien gibt.
  • das Interpretieren der Daten im RS ist etwas umständlicher


Aber es ist zumindest der Abfrage der Unterkategorien pro Hauptkategorie in einer Schleife vorzuziehen. Die beste Lösung für derartige Probleme sind aber sicher Nested Sets. Dazu ist aber das Tabellenlayout und ggf. auch der Code zur Verwaltung dieser Daten anzupassen.

9

Friday, November 20th 2009, 11:37pm

Die Lösung ist ganz einfach du brauchst weder eine noch eine 2 while scheife. Sowie auch ein Sql befehl der dich hier nicht viel weiter bringt.
Das was du benötigst dafür ist eine Rekusive Funktion. Aber vorsicht dabei das du keine Endlos Schleife damit erzeugst.

Mfg Splasch

10

Friday, November 20th 2009, 11:56pm

Die Lösung ist ganz einfach du brauchst weder eine noch eine 2 while scheife. Sowie auch ein Sql befehl der dich hier nicht viel weiter bringt.
Das was du benötigst dafür ist eine Rekusive Funktion. Aber vorsicht dabei das du keine Endlos Schleife damit erzeugst.

Mfg Splasch



Er nicht mittels einer Schleife die Abfrage durchführen aber durch Rekursion?
Nein, bestimmt nicht.

Halte dich lieber an die anderen Posts ;)

11

Saturday, November 21st 2009, 12:48am

@splasch: Datenbankabfragen sind teuer! Deshalb ist eine Lösung, die mit O(n) = 1 (z.B. mein Vorschlag oder eben Nested Sets) auskommt einer mit O(n) = n (geschachtelte Schleifen oder Rekursion) deutlich vorzuziehen.

Anmerkung für Informatiker: O(n) soll sich hier nur auf das Laufzeitverhalten bezüglich der Datenbankabfragen beziehen, nicht auf den restlichen Code. Nur am Rande, bevor ich mich hier in die Nesseln setze. ;)

12

Saturday, November 21st 2009, 8:53am

@splasch: Datenbankabfragen sind teuer! Deshalb ist eine Lösung, die mit O(n) = 1 (z.B. mein Vorschlag oder eben Nested Sets) auskommt einer mit O(n) = n (geschachtelte Schleifen oder Rekursion) deutlich vorzuziehen.

Anmerkung für Informatiker: O(n) soll sich hier nur auf das Laufzeitverhalten bezüglich der Datenbankabfragen beziehen, nicht auf den restlichen Code. Nur am Rande, bevor ich mich hier in die Nesseln setze. ;)

Da komme ich gerade nicht ganz mit. Wenn er alle Kategorien ausgeben will. Wieso reicht dann nicht ein einfaches "SELECT * FROM 'blubber'"? Er kann die Daten ja in PHP weiter verarbeiten und sortieren. (Sprich durch eine Schleife laufen lassen, die ihm das ganze dann in die richtige Reihenfolge bringt...
Latest blogs Latest blogs: Bloggen...

13

Saturday, November 21st 2009, 9:19am

Das wäre auch noch eine Möglichkeit. Dann mußt du die Daten der Kategorien aber in einer geeigneten Datenstruktur ablegen (ein zweidimensionales Array, oder besser noch ein Array von Objekten) und dich vor allem selber um die Sortierung kümmern. Da finde ich es einfacher die Arbeit direkt vom Datenbankserver erledigen zu lassen.

14

Saturday, November 21st 2009, 1:59pm

Mhm,

könntest du das im Rahmen dieses Threads mal erklären? Eventuell mit einer angedeuteten Datenbankstruktur? Das würde mich schon sehr interessieren.
Latest blogs Latest blogs: Bloggen...

15

Saturday, November 21st 2009, 2:24pm

Wie gesagt, das richtige Stichwort lautet Nested Sets.

Da man Bäume nicht mit SQL mit einem Select darstellen kann, bedarf es eben "komplexeren" Schreiboperationen um die gesamte Hierarchie mit einem SELECT lesen zu können.
Auf der Wikipedia Seite zu Nested Sets findest du auch ein MySQL 5 Stored Procedure Beispiel. Damit ist die Handhabung nicht mehr so kompliziert.
Das Datenbank Modell ist ganz simpel: "Links, Rechts, Bezeichnung". Links und Rechts zeigen jeweils auf die Elternknoten.

Ich persönlich implementiere übrigens keine Nested Sets für eine Navigation, die sich maximal 1x die Woche (oder eher 1x im Jahr) ändert.
Die Komplexität reduziere ich mir lieber indem ich das Datenbankmodell in ein Array auslese, cache und dann lesen.

Social bookmarks