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),那么它将返回 Chapt=1,而正确答案是 2。

它们是您查询中的其他错误。

仅使用开始段落和结束段落定义章节范围意味着在这些边界之间,所有段落 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 回答