Ich habe eine Produkttabelle, die eine FK für eine Kategorie enthält. Die Tabelle Kategorien wurde so erstellt, dass jede Kategorie eine übergeordnete Kategorie haben kann, zum Beispiel:
%Vor%Ich muss eine Select-Abfrage machen, dass, wenn die ausgewählte Kategorie Prozessoren ist, es Produkte zurückgibt, die in Intel, Pentium, Core 2 Duo, Amd usw. enthalten sind.
Ich habe überlegt, eine Art "Cache" zu erstellen, der alle Kategorien in der Hierarchie für jede Kategorie in der Datenbank speichert und das "IN" in die where-Klausel aufnimmt. Ist das die beste Lösung?
Die beste Lösung hierfür ist die Datenbankentwicklung. Ihre Kategorietabelle muss ein geschachtelter Satz sein. Der Artikel Hierarchische Daten in MySQL verwalten ist nicht so MySQL-spezifisch (trotz des Titels), und gibt einen guten Überblick über die verschiedenen Methoden zum Speichern einer Hierarchie in einer Datenbanktabelle.
Wenn Ihre Hierarchietabelle also ein geschachtelter Satz wäre, würde Ihre Abfrage also in etwa so aussehen:
%Vor% Die 2 und 11 sind jeweils links und rechts von Processors
record.
Sieht wie ein Job für einen gemeinsamen Tabellenausdruck aus ... etwas in der Art von:
%Vor%Das sollte die Kategorie auswählen, deren Name "Prozessoren" und deren Nachfolger ist, sollte in der Lage sein, das in einer IN-Klausel zu verwenden, um die Produkte zurückzuziehen.
Ich habe in der Vergangenheit ähnliche Dinge gemacht, zuerst nach den Kategorie-IDs gesucht und dann nach den Produkten "IN" dieser Kategorien gesucht. Es ist schwer, die Kategorien zu bekommen, und Sie haben einige Optionen:
Gespeicherte Prozeduren können helfen, wenn Sie diese App-Seite nicht machen möchten.
Was Sie finden wollen, ist die transitive Schließung der Kategorie "Eltern" -Beziehung. Ich nehme an, dass es keine Beschränkung für die Kategorie-Hierarchie-Tiefe gibt, so dass Sie keine einzige SQL-Abfrage formulieren können, die alle Kategorien findet. Was ich tun würde (in Pseudocode) ist das:
%Vor%Such einfach weiter nach Kindern, bis keine mehr gefunden werden. Dies verhält sich in Bezug auf die Geschwindigkeit gut, es sei denn, Sie haben eine degenerierte Hierarchie (z. B. 1000 Kategorien, die jeweils ein Kind eines anderen sind) oder eine große Anzahl von Gesamtkategorien. Im zweiten Fall könnten Sie immer mit temporären Tabellen arbeiten, um den Datentransfer zwischen Ihrer App und der Datenbank klein zu halten.
Vielleicht etwas wie:
%Vor%[EDIT] Wenn die Kategorietiefe größer als eins ist, würde dies Ihre innerste Abfrage bilden. Ich vermute, dass Sie eine gespeicherte Prozedur entwerfen könnten, die in der Tabelle einen Drilldown ausführen würde, bis die von der inneren Abfrage zurückgegebenen IDs keine untergeordneten Elemente hatten - wahrscheinlich ein Attribut, das eine Kategorie als Endknoten in der Hierarchie kennzeichnet Führen Sie die äußere Abfrage für diese IDs aus.
Der letzte Teil des Beispiels funktioniert nicht wirklich, wenn Sie es gerade so ausführen. Entfernen Sie einfach die Auswahl aus den Produkten und ersetzen Sie sie mit einem einfachen SELECT * FROM r
Dies sollte alle "Kinder" -Kategorien ab einer bestimmten Kategorie wiederholen.
%Vor%Meine Antwort auf eine andere Frage von vor ein paar Tagen gilt hier ... Rekursion in SQL
Es gibt einige Methoden in dem Buch, die ich verlinkt habe, die Ihre Situation gut abdecken sollten.
Tags und Links sql sql-server hierarchy select