SQLite3 - 带填充和连接的计算 SELECT

问题描述

我有以下 sqlite 表(真实表的存根,其中包含一些其他列)

CREATE TABLE IF NOT EXISTS fingers(id INTEGER,intLL INTEGER,fracLat INTEGER,fracLng INTEGER,PRIMARY KEY(id)) WITHOUT ROWID;

此表中的一个典型条目是

INSERT INTO fingers(id,intLL,fracLat,fracLng) VALUES(1,12899,42513,4025);

我不时需要查询此表以提取匹配 intLL 值的行,以使计算值满足可变条件。例如

SELECT * FROM fingers WHERE intLL = 12899 AND ('8508' = (CAST((ROUND(CAST(fracLat AS REAL)/500)) 
AS INTEGER) || CAST((ROUND(CAST(fraCLng AS REAL)/500)) AS INTEGER)));

说明

  • 通过将 fractLatfracLng 列除以 10,250 或 500 来转换它们。需要 CAST AS REAL 以防止 sqlite 执行的认整数除法
  • 将十进制结果四舍五入到最接近的整数。舍入后,认情况下您将获得带有尾随 .0 的值。 CAST AS INTEGER 确保将其删除
  • 连接两部分。串联出错了。在本例中,连接结果将是 858 这不是我想要的
  • 与传入值进行比较:在本例中为 8508。

我的问题

  1. 在连接之前需要时如何用 0 填充两个部分以确保它们具有相同的位数
  2. 有没有更简单的方法来实现这一目标?

解决方法

填充 0 的一种方法是在数字的开头连接 00,并使用 SUBSTR() 返回最后 2 个字符。
此外,您可以除以 500.0 以避免整数除法:

SELECT * FROM fingers 
WHERE intLL = 12899 
AND '8508' = SUBSTR('00' || CAST(fracLat / 500.0 AS INTEGER),-2) || 
             SUBSTR('00' || CAST(fraCLng / 500.0 AS INTEGER),-2)

另一种方法是使用函数 printf() 格式化数字:

SELECT * FROM fingers 
WHERE intLL = 12899 
AND '8508' = printf('%02d',fracLat / 500.0) || 
             printf('%02d',fraCLng / 500.0)

参见demo