1

私はこのスキーマを持っています:

Story
_id 
name

Paragraph
_id
text 
story_id

( the chapter can start from a specific story and 
a specific paragraph and
ends with a specific story and specific paragraph).

Chapter
_id
name 
start_story_id
start_paragraph_id( first paragraph id in the story which _id == start_story_id) 
end_story_id
end_paragraph_id ( last paragraph id in the story which  _id == end_story_id)

特定の段落がどの章にあるか知りたいです。ストーリーIDと段落IDがあります。これは私がこれまでに試したことであり、この正しい結果が得られます:

SELECT MIN(_id) 
FROM   chapter 
WHERE  ( start_story_id = @param_story_id 
         AND start_paragraph_id >= @param_parahgraph_id ) 
        OR ( end_story_id = @param_story_id 
             AND end_paragraph_id >= @param_parahgraph_id ) 
        OR ( @param_story_id >= start_story_id 
             AND @param_story_id <= end_story_id ) 
4

1 に答える 1

1

クエリは正しい答えを返さないはずです。あなたのデータが幸運にも整理されていない限り。

これは、ストーリーが複数のチャプターに分割されているため、クエリは常に、段落の最初のチャプターではなく、ストーリーの最初のチャプターを返すためです。

データの例:

Story: |1 1 1|2 2 2|3 3 3|
Parag: |1|2|3|4|5|6|7|8|9|
Chapt: |1 1|2 2|3|4 4|5 5|

クエリで(Parag = 3、Story = 1)を要求すると、正解が2であるのに、Chapt=1が返されます。

それらはあなたの質問における他の間違いです。

開始段落と終了段落のみで章の範囲を定義することは、これらの境界の間で、すべての段落IDが同じ章にあることを意味します。

したがって、Paragraph._idが実際に主キーである場合(スキーマで推測できるように)、クエリは単純に次のようになります。

SELECT _id
FROM chapter
WHERE (start_paragraph_id<=@param_paragraph_id)
AND (@param_paragraph_id<=end_paragraph_id)

ただし、主キーが実際に{Paragraph._id + Paragraph.story_id}である場合(チャプターテーブルがそれを意味する場合があるため)、story_idも同じチャプターで順序付けられていることを意味します。

したがって、story_idparagraph_idは両方とも、ソート値の整数部分と小数部分であるかのように段落を並べ替えています。そして、クエリは次のようになります。

SELECT MIN(_id)
FROM chapter
WHERE
 ( (start_story_id<@param_story_id)
   OR
   ( (start_story_id=@param_story_id)
     AND
     (start_parahraph_id<@param_paragraph_id) ))
 AND
 ( (end_story_id>@param_story_id)
   OR
   ( (end_story_id=@param_story_id)
     AND
     (end_parahraph_id>@param_paragraph_id) ))

クエリの複雑さは、データ配置の複雑さから来ているのではないかと思います。チャプターIDが段落テーブルにあるとよいでしょう。

于 2012-07-21T02:32:07.983 に答える