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