【问题标题】:SQLite SELECT...ordering by "best" matchSQLite SELECT ...按“最佳”匹配排序
【发布时间】:2020-03-05 14:16:44
【问题描述】:

这里的上下文是 Android 应用程序中的 SQLCipher 数据库。 这里的上下文是 Android 应用程序中的 SQLCipher 数据库。 这里的上下文是 Android 应用程序中的 SQLCipher 数据库。考虑下面的 SQLite 表

CREATE TABLE IF NOT EXISTS test(a INTEGER NOT NULL,b INTEGER NOT NULL,c INTEGER NOT NULL,d INTEGER NOT NULL);

我在其中插入以下行

INSERT INTO test (a,b,c,d) VALUES(1,2,3,4);
INSERT INTO test (a,b,c,d) VALUES(1,2,3,5);
INSERT INTO test (a,b,c,d) VALUES(1,2,5,5);
INSERT INTO test (a,b,c,d) VALUES(1,5,5,5);
INSERT INTO test (a,b,c,d) VALUES(5,5,5,5);

简单的SELECT COUNT(*) FROM test WHERE a = 1 OR b = 2 or c = 3 or d = 4; 将返回4 作为结果,因为5 行中有4 行具有一个或多个匹配值。我需要做的是找到“最佳”匹配,即最满足WHERE .. OR 条件的匹配。在本例中,这将返回 所有四个 列都匹配的第一行。虽然我可以简单地将光标返回到沿 SELECT * FROM test WHERE a = 1 OR b = 2 or c = 3 or d = 4; 行的原始选择上,然后在 Java 中完成其余的工作,但我想知道是否没有办法直接在 SQLite 本身内执行此操作。

【问题讨论】:

    标签: sqlite select


    【解决方案1】:

    使用表达式:

    (a=1) + (b=2) + (c=3) + (d=4)
    

    ORDER BY 子句中:

    SELECT *
    FROM test
    ORDER BY (a=1) + (b=2) + (c=3) + (d=4) DESC
    LIMIT 1
    

    每个术语:(a=1)(b=2)(c=3)(d=4) 对于 TRUE 的计算结果为 1,对于 FALSE 的计算结果为 0
    请参阅demo
    如果您想在结果中出现平局,请使用 CTE:

    WITH cte AS (
      SELECT *, (a=1) + (b=2) + (c=3) + (d=4) counter
      FROM test
    )
    SELECT a, b, c, d 
    FROM cte
    WHERE counter = (SELECT MAX(counter) FROM cte)
    

    请参阅demo
    或者用RANK()窗口函数:

    WITH cte AS (
      SELECT *, RANK() OVER (ORDER BY (a=1) + (b=2) + (c=3) + (d=4) DESC) rn
      FROM test
    )
    SELECT a, b, c, d 
    FROM cte
    WHERE rn = 1
    

    请参阅demo
    结果:

    | a   | b   | c   | d   |
    | --- | --- | --- | --- |
    | 1   | 2   | 3   | 4   |
    

    【讨论】:

    • 在发布问题后反思,我意识到有时我不仅需要“最佳”匹配,而且可能需要前 2 或 3 个“最佳”匹配。事实证明你也回答了这个问题!例如,将条件更改为 WHERE rn < 3RANK() 示例将返回第一个和第二个最佳匹配项。
    • 还有一个问题 - CREATE INDEX test_ndx ON test(a,b,c,d) 会导致此处的查询更快吗?
    • 我不这么认为,因为您不需要对 a、b、c、d 进行过滤或排序,而是表达式 (a=1) + (b=2) + (c=3) + (d=4)。但是你可以测试一下。
    • @DroidOS 如果您希望按顺序排列前 3 个“最佳”匹配项,还要检查 DENSE_RANK() 而不是 RANK() 且 rn
    • 来自:sqlite.org/releaselog/3_8_3.html SQLite 从 3.8.3 版开始支持 CTE,从:sqlite.org/windowfunctions.html 从 3.25.0 版开始支持窗口函数
    猜你喜欢
    • 2013-09-14
    • 2016-11-12
    • 2015-07-11
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多