尝试做与
this question相同的事情,但这次是在sqlite中.在我当前的应用程序中,我需要能够执行此类查询:
SELECT First,Last,score FROM mytable WHERE ('John','Jordan',5) <= (First,score ) AND (First,score) <= ('Mike','Taylor',50) ORDER BY First,score LIMIT 1
得到这些数据,得到(‘Liz’,’Jordan’,2)的答案:
+-------+---------+-------+ | First | Last | score | +-------+---------+-------+ | Liz | Jordan | 2 | | John | Jordan | 2 | | Liz | Lemon | 10 | | Mike | Taylor | 100 | | John | Jackson | 1000 | | Mike | Wayne | 1 | | Liz | Lemon | 20 | | Liz | Meyers | 5 | | Bruce | Jackson | 1 | +-------+---------+-------+
在sqlite中实现这一目标的最有效方法是什么?请记住,这是一个玩具示例,我的实际应用程序具有包含更多列和数据类型以及数亿行的表.
如果解决方案可以轻松扩展到更多/更少的列,那就更好了.
元组比较:
元组按字典顺序排序,这意味着序列的排序与它们的第一个不同元素的顺序相同.例如,(1,2,x)< (1,y)返回与x<相同的值.年. 值得注意的是sql-92(以及MysqL,oracle,postresql)正确实现了这一点.该标准使用“行值构造函数”来表示我称之为元组的内容.该行为在part 8.2.7,page 209中以极其详细的方式定义.
这是创建示例所必需的sql:
create table mytable ( First char(20),Last char(20),score int ); insert into mytable values ('Liz',2); insert into mytable values ('John',2); insert into mytable values ('Liz','Lemon',10); insert into mytable values ('Mike',100); insert into mytable values ('John','Jackson',1000); insert into mytable values ('Mike','Wayne',1); insert into mytable values ('Liz',20); insert into mytable values ('Liz','Meyers',5); insert into mytable values ('Bruce',1); create unique index 'UNIQ' on mytable (First,score);
解决方法
sqlite不支持元组比较.但是行构造函数是一种简写.您可以使用更复杂的WHERE子句获得相同的结果.我省略了LIMIT 1子句,以便更容易看到两个查询都返回相同的集合. (在支持行构造函数的平台上,即.)
这种比较
ROW(a,b) <= ROW(c,d)
相当于
a < c OR (a = c AND b <= d)
您可以根据需要将其扩展到尽可能多的列.
SELECT First,score FROM mytable WHERE (('John' < First) OR ('John' = First AND 'Jordan' < Last) OR ('John' = First AND 'Jordan' = Last AND 5 <= score)) AND ((First < 'Mike') OR (First = 'Mike' AND Last < 'Taylor') OR (First = 'Mike' AND Last = 'Taylor' AND score <= 50)) ORDER BY First,score Liz Jordan 2 Liz Lemon 10 Liz Lemon 20 Liz Meyers 5
我没有用数据中的NULL来测试它.
截至2018年,sqlite确实支持元组比较. OP的查询使用提供的sql语句生成预期输出.这种编写查询的方式也有效. (我发现……和…之间更具可读性.)
SELECT First,score FROM mytable WHERE (First,score ) between ('John',5) and ('Mike',score Limit 1
我不知道这是多久以前介绍的.