Antwort
 
Themen-Optionen
Alt 20.07.2006, 02:11 Nach oben    #1
leftover when bar closes
 
Benutzerbild von dsxs
 
Registriert seit: 29.06.2006
Ort: Bern
Beiträge: 123
Standard Sehr knifflige DB Abfrage [Tabellen verbinden]

Tag Leute

Komme hier nicht weiter und hoffe auf findige Köpfe.

Folgende Tabellen werden gebraucht:

'produkte', enthält alle Produkte
'kategorien' enthält alle Prduktkategorien

Produkte ist ganz einfach aufgebaut und beinhaltet ein Feld 'categorie', welches die entsprechende KategorieID enthält.

In Kategorien speichere ich diese logischerweise ab, und zwar in Multidimensioneller Manier.
Das heisst, dass ich in der Kategorien-Tabelle ein Feld 'subcategorie' habe. Ist eine Kategorie eine Hauptkategorie (also im ersten Leven, siehe bsp unten), dann ist der Wert des Feldes 0. Ist jetzt aber eine bestimmte Kategorie einer anderen Hauptkategorie untergeordnet, enthält das Feld die ID der Hauptkategorie.


So sieht die Navigation im Shop etwa aus: (die Zahl ist jeweils die ID in der DB (absichtlich zufällig, da die Kategorien dynamisch sind))

Produktekategorie 1
-- Unterkategorie 4
-- Unterkategorie 6
-- Unterkategorie 7
Produktekategorie 3
-- Unterkategorie 2
-- Unterkategorie 5
usw

Unterkat. 4,6 und 7 haben im Feld 'subcategorie' also zB den Wert 1 stehen, während Produktekategorie 1 einfach ne 0 hat.


Wenn nun bspsw. Unterkategorie 4 angewählt wurde, hole ich alle Produkte aus der DB, welche 4 als 'categorie' haben - soweit kein Problem.

Sobald jemand aber, in diesem Bsp., die Produktekategorie 1 anwählt, sollen sämtliche sich in dieser Kategorie befindenden Produkte rausgeholt werden. Und zwar

1.) Die Produkte, welche als 'categorie' 1 haben (also direkt in der Hauptkategorie Nr. 1 sitzen)
2.) Zusätzlich die Produkte, welche in Kategorie Nr. 4,6 und 7 sitzen.

Klar könnte ich erstmal die Produkte auslesen, welche in der Hauptkategorie sitzen, dann sämtliche Unterkategorien der Hauptkat. zwischenspeichern und mit foreach die in den Unterkategorien gefundenen Produkte dem bestehenden Result aus der ersten Querie anhängen. Da die Seitennavigation aber dynamisch bleiben muss (LIMIT x,y...) wäre dies viel zu umständlich.


Folgenden Code habe

(Bem: ...$top_cat ist die gewünschte Hauptkategorie, sub_cat die Unterkategorie)

Code:
$dbh_core->query("SELECT A.id,...paar einfache Selects

FROM produkte AS A 
                                    
LEFT JOIN eine andere Tabelle, klappt ohne Probleme AS B ON A.irgendwas = B.id
LEFT JOIN kategorien AS C ON A.categorie = C.id
LEFT JOIN kategorien AS D ON C.id = D.subcategorie                                 
                                    
WHERE A.wieder paar einfache Dinge 
AND A.categorie='".mysql_real_escape_string($requested['top_cat'])."'
OR A.categorie = D.id
                                                                       
ORDER BY datetime ASC, A.top_event DESC, A.title DESC
LIMIT ".mysql_real_escape_string($display_page)*8 .",".$events_per_page."");
Die Resultate aus dieser Querie sind mehr als komisch, ich schiesse mit meiner Lösung also elends am Ziel vorbei


Wäre sehr dankbar wenn mir hier jemand seine Hilfe anbietet um diesen Gerümpel zusammenzukleistern und ein korrektes Ergebnis rauszukriegen.


Danke und Gruss aus Bern,
dsxs
__________________
Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner.
ticketbörse

dsxs ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.07.2006, 09:45 Nach oben    #2
Benutzer
 
Registriert seit: 02.09.2005
Beiträge: 68
Standard

Hallo dsxs,

zum ersten würde ich die Haupt und Untercategorien in diesem Fall aufsplitten auf 2 Tabellen. dann kann man da schön mit nem join arbeiten und die tabellen verbinden. somit musst du auch nicht umständlich makieren wer Haupt oder Unterkategorie ist. Hättest du zu den Unterkategorien weitere Unterkat's, müsstest du das ganze wahrscheinlich eh anders "bauen".


somit hättest du sowas ungefähr:

PHP-Code:
$sql "SELECT produkte.*, 
               unterkategorie.*, 
               kategorie.* FROM produkte LEFT JOIN kategorie ON (produkte.cat_id = kategorie.id)
                                         LEFT JOIN unterkategorie ON (kategorie.id = unterkategorie.u_cat_id) WHERE........."


Beachte:

1. Es ist nur ein beispiel, du wirst das ganze noch ergänzen müssen.
2. Solltest du dir das Thema Joins sehr gut anschauen. Denn ich merks bei mir selbst das ich, sobald es mehr als 2 Joins sind, immernoch in meinem schlauen Buch nachsehn muss.
3. sind die spalte.* durch die Spalten zu ersetzen, war nur um das Statement zu kürzen.



Hoffe ich konnt dir damit weiterhelfen.


PS: Wäre auch nicht schlecht bei solchen dingen die komplette Tabellenstruktur zu sehen

MfG

Marcel

Geändert von Julied64 (20.07.2006 um 09:48 Uhr).
Julied64 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.07.2006, 11:54 Nach oben    #3
leftover when bar closes
 
Benutzerbild von dsxs
 
Registriert seit: 29.06.2006
Ort: Bern
Beiträge: 123
Standard

Hi Marcel und vielen Dank für die Antwort.

Deinen Tip, die Unterkategorien in eine andere Tabell auszulasten werde ich mir für weitere Projekte beherzigen - für dieses ist die Struktur aber schon zu stark in das Adminpanel und den Webshop eingenistet, dass ein ändern nur noch aufwendiger wäre.
Ich sehe hier also keine andere Möglichkeit als diese elende Abfrage endlich zum Laufen zu kriegen, die hält mich schon lange auf.

Ich habe übersichtshalber absichtlich nicht die ganze Tabellenstruktur gepostet. Geht hier mehr ums Prinzip, zusammenwürfeln kann ich die Querie dann schon...


Wie könnte ich hier vorgehen, ich will alle Produkte rausholen, und zwar die, die bei 'categorie' die ID der gewünschten Kategorie stehen haben, und zusätzlich die Produkte, die bei 'categorie' eine ID Nr. drin haben, die mit der Hauptkategorie verbunden ist (sprich: die Kategorie hat als Feld 'subcategorie' den Wert der gewünschten Hauptkategorie).

Phuu, bitte helft mir in der Sache, die Verzweiflung naht

Grüsse
__________________
Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner.
ticketbörse

dsxs ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.07.2006, 12:49 Nach oben    #4
Benutzer
 
Registriert seit: 02.09.2005
Beiträge: 68
Standard

Ich werd das heute Nacht mal testen. Komm bis dahin nimma dazu
Julied64 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.07.2006, 13:09 Nach oben    #5
Benutzer
 
Registriert seit: 20.08.2005
Beiträge: 91
Standard

Zitat:
zum ersten würde ich die Haupt und Untercategorien in diesem Fall aufsplitten auf 2 Tabellen.
Würd ich NCIHT machen... ist aber nur mein persönlicher Geschmack!
Ich würde jeder Kategorie eine übergeordnete Kategorie zuordnen, so das die Kategorien quasi "gleichberechtigt" sind...
Zitat:
Wie könnte ich hier vorgehen, ich will alle Produkte rausholen, und zwar die, die bei 'categorie' die ID der gewünschten Kategorie stehen haben, und zusätzlich die Produkte, die bei 'categorie' eine ID Nr. drin haben, die mit der Hauptkategorie verbunden ist (sprich: die Kategorie hat als Feld 'subcategorie' den Wert der gewünschten Hauptkategorie).

Phuu, bitte helft mir in der Sache, die Verzweiflung naht
Du könntest versuchen zu jedem Artikel einen Kategoriebaum zu speichern, nach dem Schema 0-8-15 (Kat-Unter-unterkat-...), dort kannst Du dann feststellen ob der Artikel in der entspr. Kategorie enthalten ist...

mfg
Homepagespeicher ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.07.2006, 13:41 Nach oben    #6
Jay
Gast
 
Beiträge: n/a
Standard

Du willst also einfach eine Baumstruktur auslesen? Dann ist das naheliegendste eine Rekursive Funktion, weil das schnell gemacht ist und nicht viel Denkarbeit braucht. Allerdings sind rekusive Queries nicht gerade schnell. Es gibt auch noch verschachtelte Mengen (auch Nested Sets, Binärebäume genannt). Da sendest du nur einen Query an die DB, weshalb das wesentlich schneller ist. Allerdings ist der Updateprozess wesentlich blöder.

Ich würde verschachtelte Mengen nehmen

EDIT:
Das ist doch eigentlich schon 100.000mal gefragt worden in diesem Forum. Vielleicht will ja jemand ein Tut dazu schreiben.

Jay
 
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 20.07.2006, 17:55 Nach oben    #7
leftover when bar closes
 
Benutzerbild von dsxs
 
Registriert seit: 29.06.2006
Ort: Bern
Beiträge: 123
Standard

Hab's hingekriegt.
Nicht sehr schön, aber es klappt wunderbar.

Ich hole vor der Query sämtliche Unterkategorien der jeweiligen Hauptkategorie raus und bastle aus dem Resultat einen "OR categorie ='x' OR categorie='y'uswusw "-String, den ich mit in die Querie packe.

Sowas müsste aber mit einer einzigen Querie schon gehn oder?
JOINS verwende ich erst seit gut zwei Wochen, bin da noch sehr unerfahren und blicke noch überhaupt nicht durch... Übung macht den Meister

Grüsse
__________________
Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner.
ticketbörse

dsxs ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 21.07.2006, 09:18 Nach oben    #8
Lutz
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 684
Standard

Eine vielleicht einfachere Methode wäre eine künstliche Redundanz zu schaffen, um die Performance zu steigern. Ich würde in diesem Falle ein weiteres Feld vorschlagen, in welchem der Key zur "obersten" Element angegeben wird. Sprich: Man hat eine UID, eine SubUID und eine ParentUID. Ist die SubUID beim "obersten" Element also 0, wird der Wert in ParentUID der UID gleichgesetzt. Bei den Elementen der ersten Ebene "unter" diesem Element, wird der Wert aus ParentUID einfach übernommen, ebenso wie bei jeder weiteren Ebene eine Stufe "tiefer" vom direkt darüberliegenden Element der Wert ParentUID übernommen wird. Nun kann man einfach nach der ParentUID suchen nund bekommt in einer abartigen Geschwindigkeit nur das ausgegeben, was man haben will. Sucht man in einer untergeordneten Ebene, muss man hinterher halt noch die darüberliegenden Ebenen ausfiltern, aber das ist ansich ja kein Problem, ich denke jedenfalls, dass das deutlich performanter sein wird, als 2 DB-Queries laufen zu lassen.

Es ist aber auch nur eine Idee / Denkanstoß. Ihr könnt
ja mal konstruktive Kritik üben, was ihr daran gut oder schlecht findet
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 21.07.2006, 14:50 Nach oben    #9
Benutzer
 
Registriert seit: 20.08.2005
Beiträge: 91
Standard

Der Vollständigkeit halber geb ich nochmal Senf dazu:
Zitat:
Es ist aber auch nur eine Idee / Denkanstoß. Ihr könnt
ja mal konstruktive Kritik üben, was ihr daran gut oder schlecht findet
Zitat:
Eine vielleicht einfachere Methode wäre eine künstliche Redundanz zu schaffen, um die Performance zu steigern.
Zitat:
Sucht man in einer untergeordneten Ebene, muss man hinterher halt noch die darüberliegenden Ebenen ausfiltern, aber das ist ansich ja kein Problem, ich denke jedenfalls, dass das deutlich performanter sein wird, als 2 DB-Queries laufen zu lassen.
Das passt irgendwie nicht ganz, oder versteh ich nicht ganz wie Du das meinst!

Hier muß wieder getrennt werden:
Kategorisierung - Suchmethodik

Kategorisierung:
Ich glaube MrNiceGuy wollte da das gleiche sagen wie ich:
Kurzbeispiel:
TABLE kategorien (
id -> Primärschlüssel
_id -> übergeordnete Kategorie (entsprechend MrNiceGuy's ParentID)
katname, etc...
)

0 ist die Hauptkategorie, wenn _id = 0 ist es also eine Hauptkategorie
wenn Kategorie ID 1=> Fahhrad (mit_id0) ist wäre Reifen beispielsweise ID 2 mit _id 1 .

Aber soweit warst Du ja schon:
Zitat:
In Kategorien speichere ich diese logischerweise ab, und zwar in Multidimensioneller Manier.
Das heisst, dass ich in der Kategorien-Tabelle ein Feld 'subcategorie' habe. Ist eine Kategorie eine Hauptkategorie (also im ersten Leven, siehe bsp unten), dann ist der Wert des Feldes 0. Ist jetzt aber eine bestimmte Kategorie einer anderen Hauptkategorie untergeordnet, enthält das Feld die ID der Hauptkategorie.
Wozu SubUID+PArentID dann gut sein soll versteh ich jetzt noch nich... hört sich an wird es hinundherverwechslet

Es kann natürlich vorkommen das Du einen Artikel in verschiedene Kategoriebäume einsortieren mußt, z.B.:
->Kategorisierung 1 : Fahrrad/Reifen
->Kategorisierung 2: Deinstleistungen/Flicken
(Erst hier würde eine zweite Kat Tabelle u.U. vl. Sinn machen)

Suche:
Hier braucht erst das Denken anzufangen. Je nach Anwendungsfall gibt es tausende Möglichkeiten...
Zitat:
Hab's hingekriegt.
Siehst Du
Zitat:
Sowas müsste aber mit einer einzigen Querie schon gehn oder?
*tss* merk erst jetzt irgendwie das es Dir um die Suche nach Unterkategorien und nicht um "Artikelbäume" geht, das kostet doch Geld Mensch *gr*
Aber das müßte doch NOCH einfacher gehen:
Zitat:
Ich hole vor der Query sämtliche Unterkategorien der jeweiligen Hauptkategorie raus und bastle aus dem Resultat einen "OR categorie ='x' OR categorie='y'uswusw "-String, den ich mit in die Querie packe.
Wieder an Dir vorbeidegacht,srry: - Das gleiche geht natürlich auch mit Kategorien:
Also den entsprechenden "Pfad" (das meinte ich mit "Baum") (bei der Erstellung des Artikels/Katgorie) speichern (Dann kann man sogar die komplette Tabelle mit einem query auslesen und ereg verwenden ).
Was jetzt perfomanter ist weiß ich aber jetzt nicht...

Viel Glück noch...!

mfg
Homepagespeicher ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 21.07.2006, 15:50 Nach oben    #10
Lutz
 
Benutzerbild von MrNiceGuy
 
Registriert seit: 14.08.2005
Ort: Nienburg / Weser
Beiträge: 684
Standard

Also um mal etwas Klarheit in das zu bringen, was ich meinte:

Tabelle:
UID (Primary-Key)
SubUID (Key auf Primary-Key; Wenn 0 = Hauptkategorie, wenn > 0 = Unterkategorie (aber von IRGENDEINER Kategorie, nicht zwangsläufig von einer Haupt-Kategorie!!!))
ParentUID (Key auf den Primary-Key der absoluten Haupt-Kategorie)
Name (Name der Kategorie)

Wenn man jetzt also folgende Struktur haben will:

Code:
+ - HK 1
| |
| + - UK 1.1
| | |
| | + - UK 1.1.1
| | |
| | + - UK 1.1.2
| |
| + - UK 1.2
|
+ - HK 2
Einfach um mal ein banales Beispiel zu bringen, müsste es in der DB dann wie folgt aussehen:

1 | 0 | 1 | HK 1
2 | 1 | 1 | UK 1.1
3 | 2 | 1 | UK 1.1.1
4 | 2 | 1 | UK 1.1.2
5 | 1 | 1 | UK 1.2
6 | 0 | 6 | HK 2

Es ist also klar erkennbar, welche Kategorien alle zur Haupt-Kategorie 1 gehören, somit braucht man nicht umständlich nach einem Zweig suchen, sondern kann direkt auf alle zugreifen, die dazu gehören. Sollte man sich dann in UK 1.1 z.B. befinden, muss man hinterher nurnoch den rest ausfiltern, der nicht mehr dazu gehört, hat aber trotzdem nur diese eine Abfrage in der DB, die mal wahnsinnig schnell sein dürfte.
__________________
Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll

Geändert von MrNiceGuy (21.07.2006 um 15:53 Uhr).
MrNiceGuy ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Zugriff auf Wert des vorhergenden Datensatzes in einer SQL Abfrage Jay Datenbanken 5 17.07.2006 15:25
Abfrage über zwei Datenbanken Netty Datenbanken 1 19.05.2005 06:53


Alle Zeitangaben in WEZ +2. Es ist jetzt 07:42 Uhr.


Powered by vBulletin® Version 3.7.3 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44