我的数据库如下所示:
Book,Chapter,Verse,Scripture
"1","1","1","1text1"
"1","1","2","1text2"
"1","1","3","1text3"
"1","1","4","1text4"
"1","2","1","2text1"
"1","2","2","2text2"
"1","2","3","2text3"
我想选择1,1,1到1,2,3的所有行。
但是我当前的查询不会返回第1,1,4行,因为4大于3。
SELECT * FROM my_table WHERE
Book >= 1 AND Book <= 1 AND
Chapter >= 1 AND Chapter <= 2 AND
Verse >= 1 AND Verse <= 3
答案 0 :(得分:2)
MySQL也支持row constructors。如果您想要(例如)1 1:3到1 2:2,请使用:
SELECT * FROM bible
WHERE (1,1,3) <= (book, chapter, verse) AND (book, chapter, verse) <= (1,2,2)
58 1:3到62 4:2,
SELECT * FROM bible
WHERE (58,1,3) <= (book, chapter, verse) AND (book, chapter, verse) <= (62,4,2)
58 1:4将包括在内,59 1:1和60 10:10,但不包括62 5:1。
我找不到太多文档,但是MySQL遵循自SQL-92以来为行比较设置的行为(注意:链接是草稿版本),特别是第8.2节“一般规则”7):< / p>
设R x 和R y 是比较谓词的两个行值构造函数,并且让R x i 和R y i 是R x 和R y 的第i行值构造元素,分别。 “R x [comp op] R y ”为真,假或未知如下:
[...]
c)当且仅当R x i = R <时,“R x &lt; R y ”为真对于所有i y i n和R x n &lt;对于某些n,R y n 。d)当且仅当R x i 时,“R x > R y ”为真所有i <= R y i n和R x n &gt;对于某些n,R y n 。
e)当且仅当R x = R y <时,“R x &lt; = R y ”为真/ sup>或R x &lt; [R ý
f)当且仅当R x = R y <时,“R x > = R y ”为真/ sup>或R x &gt; [R ý
第9.2节Joe Celko的SQL For Smarties(链接到第3版,但在早期版本中存在相同的主题)中讨论了行比较。
答案 1 :(得分:1)
数据模型中缺少的是Book,Chapter和verse与层次结构相关的事实。
如果对于每个条目,您还存储了将书章和诗节组合在一起的单个数据项,搜索给定范围只需要一个简单的BETWEEN运算符。
让我们说你知道没有一本书包含超过99章,而且没有章节包含999多节经文。你可以计算(Book * 100 + Chapter)* 1000 + Verse 对于存储的每个项目,并将其存储在单独的列中。 (是的,我知道这是多余的)。
然后你可以在(1 * 100 + 1)* 1000 + 1和(1 * 100 + 2)* 1000 + 5之间搜索该列 找到从1,1,1到1,2,5的所有内容。
答案 2 :(得分:0)
您需要使用OR语句。
SELECT * FROM my_table WHERE
(Book = 1 AND
Chapter BETWEEN 1 AND 2
Verse BETWEEN 1 AND 2)
OR
(/* THE OTHER STATEMENT */)
OR
(/* THE OTHER STATEMENT */)
如果您使用BETWEEN运算符
,则更加清晰答案 3 :(得分:0)
这就是我在书中选择范围时所提出的。 如果我想从1,1,3到1,7,2
SELECT * FROM Bible WHERE Book = 1 AND Chapter = 1 AND Verse >= 3
UNION
SELECT * FROM Bible WHERE Book = 1 AND Chapter >1 AND Chapter <7
UNION
SELECT * FROM Bible WHERE Book = 1 AND Chapter = 7 AND Verse <=2
选择书籍范围:58,1,3到62,4,2
SELECT * FROM Bible WHERE Book = 58 AND Chapter = 1 AND Verse >= 3
UNION
SELECT * FROM Bible WHERE Book = 58 AND Chapter > 1
UNION
SELECT * FROM Bible WHERE Book > 58 AND Book < 62
UNION
SELECT * FROM Bible WHERE Book = 62 AND Chapter < 4
UNION
SELECT * FROM Bible WHERE Book = 62 AND Chapter = 4 AND Verse <=2
答案 4 :(得分:0)
我能想到的唯一解决方案是添加一个额外的索引列:
ALTER TABLE my_table ADD VerseIndex CHAR(10) NOT NULL, INDEX(VerseIndex(4));
UPDATE my_table SET VerseIndex = CONCAT(
LPAD(Book, 2, '0'),
'-', LPAD(Chapter, 3, '0'),
'-', LPAD(Verse, 3, '0')
);
现在,您的表中应该有一个额外的列,文本值为“ - ”,mysql可以按字母顺序搜索,为您提供精确的范围:
# find book 2 chapter 4 v 3 through to book 3 chapter 1 v 1 (inclusive)
SELECT * FROM my_table WHERE VerseIndex BETWEEN '02-004-003' AND '03-001-001' ORDER BY VerseIndex;
# find book 5 chapter 4 (whole chapter) through to book 7 end of chapter 9
SELECT * FROM my_table WHERE VerseIndex BETWEEN '05-004-000' AND '07-009-999' ORDER BY VerseIndex;