【发布时间】:2009-08-07 01:12:10
【问题描述】:
我有一个包含可变长度数字前缀记录的 sqlite 表。我希望能够以最有效的方式找到针对另一个可变长度数字的最完整前缀:
例如。该表包含一个名为 prefix 的列,其中包含以下数字:
1. 1234
2. 12345
3. 123456
找到第二条记录作为与 12345999 的最完整匹配的有效 sqlite 查询是什么。
谢谢。
【问题讨论】:
我有一个包含可变长度数字前缀记录的 sqlite 表。我希望能够以最有效的方式找到针对另一个可变长度数字的最完整前缀:
例如。该表包含一个名为 prefix 的列,其中包含以下数字:
1. 1234
2. 12345
3. 123456
找到第二条记录作为与 12345999 的最完整匹配的有效 sqlite 查询是什么。
谢谢。
【问题讨论】:
这里有个巧妙的技巧是反转 LIKE 子句——而不是说
WHERE prefix LIKE '...something...'
就像您经常做的那样,通过在末尾附加一个 % 并将其作为固定字符串与您的输入进行比较,将 前缀 转换为模式。按前缀长度降序排列,选择前 1 个结果。
我以前从未使用过 Sqlite,但刚刚下载了它,它工作正常:
sqlite> CREATE TABLE whatever(prefix VARCHAR(100));
sqlite> INSERT INTO WHATEVER(prefix) VALUES ('1234');
sqlite> INSERT INTO WHATEVER(prefix) VALUES ('12345');
sqlite> INSERT INTO WHATEVER(prefix) VALUES ('123456');
sqlite> SELECT * FROM whatever WHERE '12345999' LIKE (prefix || '%')
ORDER BY length(prefix) DESC LIMIT 1;
输出:
12345
【讨论】:
我个人使用 next 方法,它会使用索引:
语句'('1','12','123','1234','12345','123459','1234599','12345999','123459999')' 应该由客户端生成
SELECT * FROM whatever WHERE prefix in
('1','12','123','1234','12345','123459','1234599','12345999','123459999')
ORDER BY length(prefix) DESC LIMIT 1;
【讨论】:
select foo, 1 quality from bar where foo like "123*"
union
select foo, 2 quality from bar where foo like "1234*"
order by quality desc limit 1
我还没有测试过,但是这个想法可以在其他 SQL 方言中使用
【讨论】:
几个假设。
prefix_table.prefix
1234
12345
123456
etc.
foo.field
12345999
123999
select
a.field,
b.prefix,
max(len(b.prefix)) as length
from
foo a inner join prefix_table b on b.prefix = left(a.field, len(b.prefix))
group by
a.field,
b.prefix
请注意,这是未经测试的,但在逻辑上应该是有道理的。
【讨论】:
如果不求助于专门的索引,最好的策略可能是寻找答案。
对每个可能的前缀发出 LIKE 查询,从最长的开始。一旦返回行就停止。
这当然不是实现您不想要的最漂亮的方式,但与其他建议相反,查询规划器将考虑索引。与往常一样,这取决于您的实际数据。特别是,您的表中有多少行,以及平均搜索时间。
【讨论】: