Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用3个不同的索引选择一系列行_Sql_Mysql - Fatal编程技术网

Sql 使用3个不同的索引选择一系列行

Sql 使用3个不同的索引选择一系列行,sql,mysql,Sql,Mysql,我的数据库如下所示: 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

我的数据库如下所示:

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

您需要使用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 */)
编辑 如果您使用MySQL也支持的运算符,则更加清楚。如果需要,例如1 1:3到1 2:2,请使用:

SELECT * FROM bible
    WHERE (1,1,3) <= (book, chapter, verse) AND (book, chapter, verse) <= (1,2,2)
从581:3到624: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遵循为行比较设置的行为,因为注意:链接指向一个草案版本,特别是第8.2节一般规则7:

设Rx和Ry为比较谓词的两行值构造函数,Rxi和Ryi分别为Rx和Ry的第i行值构造函数元素。Rx[comp op]Ry为真、假或未知,如下所示: [...] 当且仅当所有i 当且仅当所有iRyn时,d Rx>Ry为真

当且仅当Rx=Ry或Rx>Ry时,e Rx=Ry为真


第9.2节乔·塞尔科(Joe Celko)链接到第三版中介绍了行比较,但在早期版本中也存在相同的主题。

这就是我在书中选择范围的想法。 如果我想从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

我能想到的唯一解决方案是添加一个额外的列用于索引:

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;

您的数据模型缺少一个事实,即书籍、章节和诗句是层次相关的

如果对于每个条目,您还存储了单个数据项,这些数据项将书籍的章节和韵文组合在一起,那么搜索给定的范围只需要一个简单的BETWEEN运算符

假设你知道没有一本书包含超过99章,也没有一章包含超过999节的诗句。你可以计算书*100+章*1000+节 对于存储的每个项目,并将其存储在单独的列中。是的,我知道这是多余的

然后可以在1*100+1*1000+1和1*100+2*1000+5之间搜索该列
查找从1,1,1到1,2,5的所有内容。

我认为缺少了一些内容。既然你似乎想要第1册中的所有内容,为什么不省略章节标准呢?你能再详细说明一下你的要求吗?您希望在查询时排除哪些数据?该表有66本书,每本书最多有100或更多章节,每章最多有100或更多诗句。我希望能够选择1,1,1到1,5,5或2,4,3到3,1,1。@Daniel:在任何给定时间编写一个SQL查询来处理所有筛选条件都是不现实的。例如,请参见我的答案。@rexem:那么,如果我想要1,1,$x到2,5,$y,我需要连接三个不同的select语句吗?处理第一章中大于$x的诗句的第一个查询。第二个查询,用于处理第一章和最后一章之间的所有诗句。第三个查询处理最后一章中的诗句少于$y。除非我检查,否则我不知道一章中有多少诗句。例如,我想选择第1章中的所有章节,但在第2章中我只想选择第5节。这看起来很有希望,不幸的是手册页面太模糊了,无法确定这是否是Daniel真正需要的功能。::叹气::如果你要使用工会,使用UNION ALL,因为不会删除重复行,并且结果包括所有SELECT语句中的所有匹配行。