问题描述
我有以下 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)));
说明
- 通过将
fractLat
和fracLng
列除以 10,250 或 500 来转换它们。需要CAST AS REAL
以防止 sqlite 执行的默认整数除法 - 将十进制结果四舍五入到最接近的整数。舍入后,默认情况下您将获得带有尾随
.0
的值。CAST AS INTEGER
确保将其删除 - 连接两部分。串联出错了。在本例中,连接结果将是 858 这不是我想要的
- 与传入值进行比较:在本例中为 8508。
我的问题
- 在连接之前需要时如何用 0 填充两个部分以确保它们具有相同的位数
- 有没有更简单的方法来实现这一目标?
解决方法
填充 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。