【问题标题】:sqLite OFFSET query does not work with WHERE clause?sqLite OFFSET 查询不适用于 WHERE 子句?
【发布时间】:2023-03-15 05:19:02
【问题描述】:

谁能解释一下为什么这个 sqlite3 查询会起作用并返回我的 1000 条记录:

SELECT * FROM fmsdata LIMIT 1000 OFFSET (SELECT COUNT(*) FROM fmsdata) - 1000

但是当我加入 where 子句 WHERE valve=3 的那一刻,它什么也没返回?

SELECT * FROM fmsdata WHERE valve=3 LIMIT 1000 OFFSET (SELECT COUNT(*) FROM fmsdata) - 1000

此子查询返回表大小为 123290。

SELECT COUNT(*) FROM fmsdata

仅供参考,偏移量只是为了快速给我数据库的尾部而无需对任何内容进行排序,因为我知道最新的记录总是在末尾。

这是一个没有 where 子句的成功查询:

我们的测试表有大约 102 个阀门循环的记录,因此在限制为 1000 个的情况下,我们应该至少有 9 个条目出现在查询的末尾。

不确定是否重要,但我使用的是 Ubuntu 18.04 系统。

【问题讨论】:

    标签: sqlite where-clause offset sql-limit


    【解决方案1】:

    这个查询:

    SELECT * FROM fmsdata WHERE valve=3 LIMIT 1000 OFFSET (SELECT COUNT(*) FROM fmsdata) - 1000
    

    根据你的数据,相当于:

    SELECT * FROM fmsdata WHERE valve=3 LIMIT 1000 OFFSET 123290 - 1000
    

    SELECT * FROM fmsdata WHERE valve=3 LIMIT 1000 OFFSET 122290
    

    这被翻译成:

    从 Valve=3 的行中,跳过第一个 122290,然后显示给我 最多 1000 行。

    valve=3 的行是否超过 122290 行?
    我不这么认为。这就是为什么你什么都得不到。
    我想你真正想要的是这样的:

    SELECT * FROM fmsdata WHERE valve=3 
    LIMIT 1000 
    OFFSET (SELECT COUNT(*) FROM fmsdata WHERE valve=3) - 1000
    

    这意味着如果您有 1100 行 valve=3,则将跳过前 100 (= 1100 - 1000) 并选择剩余的 1000。
    如果 valve=3 的行数为 1000 或更少,则将选择所有这些行。
    附注
    当您使用LIMIT 而不使用ORDER BY 时,您必须注意不能保证结果是准确的。

    【讨论】:

    • 优秀的答案。我会强调你的最后一句话。 OP 语句“仅供参考,偏移量只是为了快速给我数据库的尾部而无需对任何内容进行排序,因为我知道最新的记录总是在末尾。”真的是一切错误的。 @simgineer 你永远不应该假设这个没有ORDER BY DESCLIMIT 语句会带回插入到表中的最后一条记录
    • 你永远不应该假设......这就是重点。任何未记录的内容,即使看起来显而易见都可能出错。
    • 在子查询中添加 WHERE 子句可以解决所有问题。我避免使用 ORDER BY 来加快查询速度,因为我们知道这些特定文件的记录将始终按时间顺序插入。我想建议是,一旦我们开始使用任何重要的操作,就不再保证实际订单。谢谢你的回答。
    猜你喜欢
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2010-10-03
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多