Frage

Ich versuche, ein Pfadaufzählungsmodell nach Joe Celko zu implementieren Buchen (Seite 38). Die relevanten Attribute meiner Tabelle (und die Support -Tabelle, die nur sequenzielle ganze Zahlen enthält) sehen Folgendes aus:

Contribution
------------
ContributionID
PathString

_IntegerSeries
--------------
IntegerID

_InteGerSeries enthält Ganzzahlen 1 bis n, wobei n größer ist, als ich jemals gebraucht werde. Der Beitrag enthält drei Datensätze:

1  1
2  12
3  123

... und ich verwende eine modifizierte Version von Joes Abfrage:

SELECT SUBSTRING( c1.PathString
     FROM (s1.IntegerID * CHAR_LENGTH(c1.ContributionID))
     FOR CHAR_LENGTH(c1.ContributionID)) AS ContID
FROM
 Contribution c1, _IntegerSeries s1
WHERE
 c1.ContributionID = 3
 AND s1.IntegerID <= CHAR_LENGTH(c1.PathString)/CHAR_LENGTH(c1.ContributionID);

... um ein Ergebnis -Set erfolgreich zurückzugeben, das alle Vorgesetzten von Beitrag ID 3 in der Hierarchie enthält. In diesem Beispiel enthält die Pathstring -Spalte einfache Ganzzahlwerte und wir werden offensichtlich in Schwierigkeiten geraten, sobald wir auf die Aufgabe 10 getroffen haben. Daher ändern wir die Pathstring -Spalte, um Separatoren einzuschließen:

1   1.
2   1.2.
3   1.2.3.

Jetzt ... gibt das Buch kein Beispiel dafür, Vorgesetzte zu bekommen, wenn der Pfad Grenzwerte verwendet ... also muss ich das später herausfinden. Aber es gibt ein Beispiel dafür, wie man einen Pfadstring aufteilt (was mir vermute, dass ich überlegene Suchanfragen durchführen werde). Die MySQL -Version des Beispielcodes, um dies zu tun, lautet:

SELECT SUBSTRING( '.' || c1.PathString || '.'
     FROM s1.IntegerID + 1
     FOR LOCATE('.', '.' || c1.PathString || '.', s1.IntegerID + 1) - s1.IntegerID - 1) AS Node
FROM _IntegerSeries s1, Contribution c1
WHERE
 SUBSTRING('.' || c1.PathString || '.' FROM s1.IntegerID FOR 1) = '.'
 AND IntegerID < CHAR_LENGTH('.' || c1.PathString || '.');

... aber dieser Code gibt ein leeres Ergebnissatz zurück. Ich mache etwas falsch, aber ich bin mir nicht sicher, was. Ich dachte, ich würde dies an die Stackoverflow -Community weitergeben, bevor ich Joe mit einer E -Mail belästigte. Hat jemand irgendwelche Gedanken?


AKTUALISIEREN


Quassnois Abfrage ... etwas nach dem Testen leicht modifiziert, aber genau das gleiche wie sein ursprünglich funktionell. Sehr schön. Viel sauberer als das, was ich benutzte. Vielen Dank.

SET @contributionID = 3;

SELECT  ca.*
FROM
    Contribution c INNER JOIN _IntegerSeries s
        ON s.IntegerID < @contributionID AND SUBSTRING_INDEX(c.PathString, '.', s.IntegerID) <> SUBSTRING_INDEX(c.PathString, '.', s.IntegerID + 1)
    INNER JOIN Contribution ca
        ON ca.PathString = CONCAT(SUBSTRING_INDEX(c.PathString, '.', s.IntegerID), '.')
WHERE c.ContributionID = @contributionID;
War es hilfreich?

Lösung

Das ist weil || in MySQL ist boolean OR, keine String -Verkettung.

Alle Vorfahren eines gegebenen zu finden Contribution, verwenden:

SELECT  ca.*
FROM    Contribution с
JOIN    IntegerSeries s
ON      IntegerID < CHAR_LENGTH(c.path)
        AND SUBSTRING_INDEX(c.path, '.', IntegerID) <> SUBSTRING_INDEX(c.path, '.', IntegerID + 1)
JOIN    Contribution ca
ON      ca.path = CONCAT(SUBSTRING_INDEX(c.path, '.', IntegerID), '.')
WHERE   c.ContributionID = 3
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top