2010-12-30 3 views
2

Joe Celkoのbook(38ページ)のようにPath Enumerationモデルを実装しようとしています。私のテーブルの関連する属性(とちょうどシーケンシャル整数を含む支持テーブル)は次のようになります。Path Enumeration Modelの分割

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

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

_IntegerSeriesを1 nは私が今まで必要がありますより大きいn個の整数が含まれています。貢献は、3つのレコードが含まれます

1 1 
2 12 
3 123 

を...と私はジョーのクエリの修正版を使用します。成功した階層にContributionID 3の上司のすべてを含む結果セットを返すように...

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); 

を。さて、この例では、PathString列は通常の整数値を保持し、我々は我々がセパレータ含めるPathString列を変更ContributionID 10ヒット後、明らかに私たちがトラブルに実行します。今

1 1. 
2 1.2. 
3 1.2.3. 

を...本は」doesnのPathStringがデリミタを使用するときに上司を得る例を挙げてください...後でそれを理解する必要があります。しかし、それはPathStringを分割する方法の例を示しています(これは私が優れた検索をするのに役立つだろうと推測しています)。これを行うサンプルコードのMySQLバージョンは、

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 || '.'); 

...ですが、このコードは空の結果セットを返します。私は何か間違っているが、私は何がわからない。私は電子メールでJoeを気にする前に、これをstackoverflowコミュニティに置くことにしました。誰でも考えがありますか?


UPDATE


Quassnoiのクエリ...少しテスト後のビットを変更したが、彼の本来の機能とまったく同じ。非常に素晴らしい。私が使っていたものよりずっときれいです。本当にありがとう。

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; 

答えて

2

MySQL||はブールOR、ない文字列の連結であるためです。

は、与えられた Contribution、使用のすべての祖先を検索するには:

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 
+0

Oouchを。私はそれよりもよく知っています。だから私は理解できなかったことに巻き込まれ、私は明らかに見落とした。しかし、きれいな質問。作業としてテストされています。ありがとうございました! – codemonkey