Willkommen in der Webstatt Zum Webstatt Blog und Stories
Rebel4s Rebel4s am 12.12.06 18:06

Hallo,
Ich habe ungefähr diesen code:

//Head Kategorien
$headcats = $db->query("SELECT * FROM cats WHERE headcatid = '0' ORDER BY sort ASC");
while($rowheadcat = $db->fetch_array($headcats)) {

//Sub Kategorien
$subcats = $db->query("SELECT * FROM cats WHERE headcatid = '$rowheadcat[catid]' ORDER BY sort ASC");

while($rowsubcat = $db->fetch_array($subcats)) {

}
}


Ich kann mir gut vorstellen, dass das ganz schön den server auslasten kann im extremfall. Geht das auch irgendwie geschickter? Per Join (was ich mir noch nicht vorstellen kann)
Oder ist die schleife die einzige lösung?

netcup.de Warum gibt es hier Werbung?
mab mab am 12.12.06 18:34

Hi,

klar geht das auch mit besserer Performance, aber dazu ist dein DB Schema momentan verkehrt, würd ich auf den ersten Blick sagen. Ist es nicht besser die subkategorien in einer anderen Tabelle zu speichern? Dann kannst du ohne Problem per left join die Daten holen:

Beispiel
cat
-----
id | name | text

subcat
-------
id | cid |name| text

$query = "SELECT a.*, b.* FROM cat AS a LEFT JOIN subcat AS b ON a.id = b.cid";

Dann musst du nur schauen, dass die subcats den normalen cats richtig zugeordnet werden, das ist eigentlich alles:

cat:
-----------
12 | natur | das ist die natur

sub cat
--------------
1 | 12 | bach | ein bach
2 | 12 | baum| ein baum

Alles klar ? :)

Grüße,
mab

Rebel4s Rebel4s am 12.12.06 18:49

würde dann bei der Methode mehr als ein Subcat aus der db ausgelesen werden?

mab mab am 12.12.06 18:57

ja, wenn ich das Statement richtig gemacht hab schon. das heißt so viel wie:

nehm den eintrag aus cat und alle subcats deren cid der id von cat entspricht:

ausgabe:

=> natur
- bach
- baum

Rebel4s Rebel4s am 12.12.06 19:15

Quote
Original von mab
ja, wenn ich das Statement richtig gemacht hab schon. das heißt so viel wie:

nehm den eintrag aus cat und alle subcats deren cid der id von cat entspricht:

ausgabe:

=> natur
- bach
- baum


versteh nur nicht wie dann die ausgabe laufen soll, wo werden dann die "bäume" gespeichert? in nem array?

mab mab am 12.12.06 20:21

left join sorgt dafür dass alle einträge mit der rechten tabelle "gematched" werden. sollte keine subcat zu der cat bestehen, wird null geliefert. die daten kannst du ganz normal ausgeben. teste doch einfach mal... du brauchst nichts zu beachten, außer die reihenfolge bei LEFT JOIN ON ....

Rebel4s Rebel4s am 12.12.06 20:52

Quote
Original von mab
left join sorgt dafür dass alle einträge mit der rechten tabelle "gematched" werden. sollte keine subcat zu der cat bestehen, wird null geliefert. die daten kannst du ganz normal ausgeben. teste doch einfach mal... du brauchst nichts zu beachten, außer die reihenfolge bei LEFT JOIN ON ....


Geht das denn nichtmit Headcats und Subcats in einer Tabelle?
Denn außer der äußerlichen formatierung auf der Seite unterscheiden die sich nicht und da ist die verwaltung mit einer tabelle einfacher.

mab mab am 13.12.06 18:56

klar, das kannst du machen, wie du es einfacher findest.
ich find es mit zwei Tabellen nicht nur geschickter, so ist es auch korrekt. je nach umfang deines projektes, kann es sein, dass mit der zeit kleine problemchen auftreten.

Rebel4s Rebel4s am 13.12.06 18:57

Quote
Original von mab
klar, das kannst du machen, wie du es einfacher findest.
ich find es mit zwei Tabellen nicht nur geschickter, so ist es auch korrekt. je nach umfang deines projektes, kann es sein, dass mit der zeit kleine problemchen auftreten.


Es werden glaub ich max. 20-30 einträge geben in der Tabelle, bringt es was bei dieser größenordnung?

mab mab am 13.12.06 19:04

keine Ahnung, denke eher weniger. Du kannst ja die Geschwindigkeit messen :D

Es kommt eigentlich nur drauf an, ob du jetzt ein gescheites Tabellen Design möchtest oder du dich mit so nem Mix zufrieden gibst. Mehr gibts dazu nicht zu sagen. :tired:

Rebel4s Rebel4s am 14.12.06 13:55

Quote
Original von mab
keine Ahnung, denke eher weniger. Du kannst ja die Geschwindigkeit messen :D

Es kommt eigentlich nur drauf an, ob du jetzt ein gescheites Tabellen Design möchtest oder du dich mit so nem Mix zufrieden gibst. Mehr gibts dazu nicht zu sagen. :tired:


wirklich zufrieden bin ich nicht, aber auch zu faul alles zu ändern^^
Aber ich denke ich werds ändern.

Rebel4s Rebel4s am 25.12.06 11:43

Bin grade dabei es zu ändern, aber irgendwas stimmt da nicht:

$cats = $db->query("SELECT * FROM headcats LEFT JOIN subcats ON(headcats.catid = subcats.headcatid) ORDER BY headcats.sort ASC, subcats.sort ASC");

while($rowcat = $db->fetch_array($cats)) {

$tpl->set_bit("tablecolor", table_ab());
$tpl->set_bit("cat_id", $rowcat['catid']);
$tpl->set_bit("cat_catname", $rowcat['catname']);

$tpl->getbit("navi_cats_showbit", "navi_cats_showbit");

}


gibt folgenden array aus:

Array
(
[0] => 3
[catid] =>
[1] => test4
[catname] =>
[2] => 0
[sort] =>
[3] =>
[4] =>
[5] =>
[headcatid] =>
[6] =>
)


Headcats:
catid catname sort
1 test1 2
2 test3 1
3 test4 0
4 asdasdasd 0


subcats:
catid catname headcatid sort
1 aaa 1 2
2 bbbb 1 1

mab mab am 25.12.06 13:06

mh, kann im Moment nicht viel erkennen. Aber schau für den Anfang , dass für jeden Eintrag aus cat ein Eintrag aus subcat existiert!!! Die Sortierung am Anfang mal weglassen, auf die Reihenfolge beim Join achten.

Rebel4s Rebel4s am 25.12.06 13:09

Quote
Original von mab
mh, kann im Moment nicht viel erkennen. Aber schau für den Anfang , dass für jeden Eintrag aus cat ein Eintrag aus subcat existiert!!! Die Sortierung am Anfang mal weglassen, auf die Reihenfolge beim Join achten.


Nicht jede Headcat hat momentan auch subcats, kann man das auch machen, dass es nicht so sein muss?

mab mab am 25.12.06 13:20

das müsste mit Inner Join gehen. Damit werden dann aber die "leeren" Einträge ganz ausgelassen. Am besten du liest dich mal dort ein: http://www.sql-tips.de/index.php/INNER_JOIN_-_OUTER_JOIN

Wenn es mal funktoniert, dann hast du echt ne ordentliche Abfrage.. ich find das lohnt sich schon.

Rebel4s Rebel4s am 27.12.06 10:32

ich komm damit echt nicht zurecht, könnt das mal einer für mich machen, der weiß wie es geht?

Problem ist, dass er immer nur die subcats oder nur die headcats ausgibt. Hab schon alle joins ausprobiert, oder ich bin einfach zu blöd, um die daten auszugeben.
Also gibt mal bitte einer ne Lösung.

Das Problem könnte auch sein, dass z.B. jedem headcat mehrere subcats zugeordnet werden, ich aber pro headcat nur ein schleifendurchlauf habe und in diesem durchlauf nicht die subcats ausgebe.
Wie kann ich dann in einem schleifendurchlauf die subcats ausgeben?

Rebel4s Rebel4s am 28.12.06 12:15

Ok, Ich bin schonmal ein stück weiter, jedoch scheitert es noch an der Ausgabe.

Momentan sieht es so aus:
$cats = $db->query("SELECT h.*, s.* FROM headcats AS h LEFT JOIN subcats AS s ON h.headcatid = s.headcatid GROUP BY h.headcatid, s.headcatid ORDER BY h.headcatsort ASC, s.subcatsort ASC");

while($rowcat = $db->fetch_array($cats)) {

$tpl->set_bit("tablecolor", table_ab());
$tpl->set_bit("cat_id", $rowcat['catid']);
$tpl->set_bit("cat_catname", $rowcat['headcatname'].' '.$rowcat['subcatname']);

$tpl->getbit("navi_cats_showbit", "navi_cats_showbit_subcats");

}


Problem ist, das er die von de subcats immer nur 1 ausgibt.
Muss man die subcats (weils mehrere sein werden) in einen array packen? Wie mach ich das?

Also Ausgabe ist dann so:

headcat4 subcat1
headcat4 subcat2
headcat3
headcat1

Ich bräuchte das so:
headcat4
subcat1
subcat2
headcat3
headcat1

mab mab am 28.12.06 13:03

Hi..

Irgendwie versteh ich grad nicht wo es hängt :rolleyes: Kannst du noch mal deine Tabellen mit Einträgen zeigen.. schön geordnet.

Rebel4s Rebel4s am 28.12.06 13:16

Quote
Original von mab
Hi..

Irgendwie versteh ich grad nicht wo es hängt :rolleyes: Kannst du noch mal deine Tabellen mit Einträgen zeigen.. schön geordnet.


subcats:
subcatid subcatname headcatid subcatsort
1 aaa 3 2
2 bbbb 3 1


headcats:
headcatid headcatname headcatsort
1 test1 2
2 test3 1
3 test4 0


Die TAbellen sollten eiegntlich stimmen, das Problem ist, dass er die subcats nicht ohne headcat ausgibt wie in den Beispiel was ich zuvor gemacht hatte.

mab mab am 28.12.06 15:07

ok, verstehe. versuch mal das

über Gruppierung

$cats = $db->query("SELECT h.*, s.* FROM headcats AS h LEFT JOIN subcats AS s ON h.headcatid = s.headcatid GROUP BY h.headcatname");


Falls das nicht taugt dann über DISTINCT


$cats = $db->query("SELECT DISTINCT h.headcatname, s.* FROM headcats AS h LEFT JOIN subcats AS s ON h.headcatid = s.headcatid");



Wenn das auch nicht hilft, dann hab ich keine Ahnung :D Du musst die Abfrage um deine entsprechenden Felder erweitern.

Hope it helps ;-)

Grüße,
mab

Rebel4s Rebel4s am 28.12.06 17:49

Hab das nun so versucht zu lösen, was aber nciht richtig funktioniert:

$cats = $db->query("SELECT h.*, s.* FROM headcats AS h LEFT JOIN subcats AS s ON h.headcatid = s.headcatid ORDER BY h.headcatsort ASC, s.subcatsort ASC");

while($rowcat = $db->fetch_array($cats)) {


if($last_headcatid != $rowcat['headcatid'])
{
$tpl->set_bit("tablecolor", table_ab());
$tpl->set_bit("cat_id", $rowcat['catid']);

$tpl->set_bit("cat_catname", $rowcat['headcatname']);

$tpl->getbit("navi_cats_showbit", "navi_cats_showbit_subcats");
}
if(!empty($rowcat['subcatid']))
{
$tpl->set_bit("tablecolor", table_ab());
$tpl->set_bit("cat_id", $rowcat['catid']);

$tpl->set_bit("cat_catname", $rowcat['subcatname']);

$tpl->getbit("navi_cats_showbit", "navi_cats_showbit_subcats");
}
$last_headcatid = $rowcat['headcatid'];
}

mab mab am 28.12.06 17:55

das mit distinct ging nicht?? hab ähnliche statements selbst im einsatz. mh hauptsache es läuft jetzt :)

Rebel4s Rebel4s am 28.12.06 18:46

Quote
Original von mab
das mit distinct ging nicht?? hab ähnliche statements selbst im einsatz. mh hauptsache es läuft jetzt :)


Gab mir genau die gleiche ausgabe. Aber bin so momentan noch nicht zufrieden, da irgendwie nicht alles angezeigt wird.

mab mab am 28.12.06 19:32

Du kannst auch mal alle Daten über phpMyAdmin abspeichern und hier als *rar anhängen. So dass ich halt bei mir gleich den Insert machen kann.
Dann schau ich drauf, falls ich Zeit hab ;)

Rebel4s Rebel4s am 28.12.06 19:40

--
-- Tabellenstruktur für Tabelle `headcats`
--

CREATE TABLE `headcats` (
`headcatid` int(11) NOT NULL auto_increment,
`headcatname` varchar(50) NOT NULL default '',
`headcatsort` int(11) NOT NULL default '0',
PRIMARY KEY (`headcatid`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Daten für Tabelle `headcats`
--

INSERT INTO `headcats` (`headcatid`, `headcatname`, `headcatsort`) VALUES (1, 'test1', 0);
INSERT INTO `headcats` (`headcatid`, `headcatname`, `headcatsort`) VALUES (2, 'test3', 1);
INSERT INTO `headcats` (`headcatid`, `headcatname`, `headcatsort`) VALUES (3, 'test4', 0);

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `subcats`
--

CREATE TABLE `subcats` (
`subcatid` int(11) NOT NULL auto_increment,
`subcatname` varchar(50) NOT NULL default '',
`headcatid` int(11) NOT NULL default '0',
`subcatsort` int(11) NOT NULL default '0',
PRIMARY KEY (`subcatid`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

--
-- Daten für Tabelle `subcats`
--

INSERT INTO `subcats` (`subcatid`, `subcatname`, `headcatid`, `subcatsort`) VALUES (1, 'aaa', 3, 2);
INSERT INTO `subcats` (`subcatid`, `subcatname`, `headcatid`, `subcatsort`) VALUES (2, 'bbbb', 3, 1);

Rebel4s Rebel4s am 29.12.06 12:24

OK, das Problem war, dass der name spalte bei den subcats "headcatid" und die Spalte bei den headcats "headcatid" war. Hab die Spalte bei den subcats in "subhcatid" umbenannt und es gibt keine Probleme mehr. (Hatte mir schon gedacht, dass es da Probleme geben kann).

Danke an die fleißigen Helfer! Konnte die Anzahl der mysql abfragen auf die hälfte reduzieren (Insgesamt)

Creative Commons Lizenzvertrag
Alle Inhalte des Webstatt-Archivs stehen unter einer Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 Unported Lizenz.

Impressum & Kontakt