在使用SQLite存储用户数据的Android应用中,有一个名为valency
的表,如下所示。
CREATE TABLE IF NOT EXISTS valency(urid INTEGER PRIMARY KEY AUTOINCREMENT,typ INTEGER,entity INTEGER,v0 INTEGER,v1 INTEGER,v2 INTEGER,v3 INTEGER,v4 INTEGER,v5 INTEGER,lato INTEGER,data INTEGER DEFAULT 0);
CREATE INDEX IF NOT EXISTS vTypEnt ON valency(typ,entity);
我需要为表v0.. v5
的{{1}}和typ
列定义表中该行的“最佳”匹配。匹配的列数越多,我想附加到匹配的entity
列上的权重就越大。
这就是我要进行的过程
步骤1-将相关行读入TEMP表
data
根据它们是否匹配,将CREATE TEMP TABLE H1 AS SELECT * FROM valency WHERE (typ = T) AND (entity = E);
值设置为1或0
v0..v5
这通常会导致UPDATE H1 SET
v0 = CASE WHEN (v0 = V0) THEN 1 ELSE 0 END,
v1 = CASE WHEN (v1 = V1) THEN 1 ELSE 0 END,
v2 = CASE WHEN (v2 = V2) THEN 1 ELSE 0 END,
v3 = CASE WHEN (v3 = V3) THEN 1 ELSE 0 END,
v4 = CASE WHEN (v4 = V4) THEN 1 ELSE 0 END,
v5 = CASE WHEN (v5 = V5) THEN 1 ELSE 0 END;
中的一个或多个行,其中零个或多个H1
的值设置为0,而其他值设置为1。我真正关心的是“最佳”匹配-即标识具有最多非零v*
个值的行。
第3步
v*
隔离具有“最佳”匹配项的行。在此结果行中使用和操作最匹配的SELECT urid,lato,data,v0 + v1 + v2 + v3 + v4 + v5 as 'vSum' FROM H1 ORDER BY vSum DESC LIMIT 1;
之前,我使用data
的大小为数据分配权重。
这有效-完美。但是,我不是SQL专家,所以我不禁想知道是否可能没有更好/更简单/更快的方法来完成同一件事。必须使用此上下文的环境不需要速度,因此我不希望在占用更多存储和更多索引的情况下进行权衡。非常感谢任何对我的方法发表评论并提出改进建议的人。
答案 0 :(得分:3)
您可以通过一次性计算得分将select转换为一个type.__new__
语句。这样就无需使用临时表,也无需在代码和数据库引擎之间进行某些往返操作:
SELECT
您可能希望向select
*
, CASE WHEN (v0 = V0) THEN 1 ELSE 0 END
+CASE WHEN (v1 = V1) THEN 1 ELSE 0 END
+CASE WHEN (v2 = V1) THEN 1 ELSE 0 END
+CASE WHEN (v3 = V3) THEN 1 ELSE 0 END
+CASE WHEN (v4 = V4) THEN 1 ELSE 0 END
+CASE WHEN (v5 = V5) THEN 1 ELSE 0 END
+ ... as vSum
FROM valency
WHERE (typ = T)
AND (entity = E)
order by vSum desc
limit 1
子句添加更多条件,以确保两次运行之间的顺序保持一致。