【发布时间】:2021-11-08 22:02:43
【问题描述】:
在本地 SQLite (vs 3.29.0) 数据库中,有一个包含 3 列的表(不包括 rowID)。两个包含值,一个包含类别。我想根据一个特定类别的值的范围来更新类别。 SET 的类别必须可能与确定范围的类别相同。
例子:
| id | Value | Value2 | Category |
|---|---|---|---|
| 1 | 20 | 20 | 2 |
| 2 | 30 | 30 | 2 |
| 3 | 40 | 40 | 2 |
| 4 | 70 | 70 | 2 |
| 5 | 5 | 5 | 1 |
| 6 | 19 | 19 | 1 |
| 7 | 26 | 26 | 1 |
| 8 | 42 | 42 | 1 |
| 9 | 49 | 49 | 1 |
| 10 | 52 | 52 | 1 |
| 11 | 71 | 71 | 1 |
| 12 | 90 | 90 | 1 |
| 13 | 17 | 17 | 1 |
我希望将行更改为类别 2,基于 value 周围的 4 范围和 value2 周围的 2 范围。这应该只更改第 6、9 和 11 行:
| id | Value | Value2 | Category |
|---|---|---|---|
| 1 | 20 | 20 | 2 |
| 2 | 30 | 30 | 2 |
| 3 | 40 | 40 | 2 |
| 4 | 70 | 70 | 2 |
| 5 | 5 | 5 | 1 |
| 6 | 19 | 19 | 2 |
| 7 | 26 | 26 | 1 |
| 8 | 42 | 42 | 2 |
| 9 | 49 | 49 | 1 |
| 10 | 52 | 52 | 1 |
| 11 | 71 | 71 | 2 |
| 12 | 90 | 90 | 1 |
| 13 | 17 | 17 | 1 |
我当前的SQL语句是:
UPDATE tablename
SET Category = 2
WHERE (Category != 2
AND EXISTS (
SELECT *
FROM tablename t
WHERE t.Category = 2
AND tablename.Value BETWEEN t.Value - 4 AND t.Value + 4
AND tablename.Value2 BETWEEN t.Value2 -2 AND t.Value2 +2)
);
其中的结果是:
| id | Value | Value2 | Category |
|---|---|---|---|
| 1 | 20 | 20 | 2 |
| 2 | 30 | 30 | 2 |
| 3 | 40 | 40 | 2 |
| 4 | 70 | 70 | 2 |
| 5 | 5 | 5 | 1 |
| 6 | 19 | 19 | 2 |
| 7 | 26 | 26 | 1 |
| 8 | 42 | 42 | 2 |
| 9 | 49 | 49 | 1 |
| 10 | 52 | 52 | 1 |
| 11 | 71 | 71 | 2 |
| 12 | 90 | 90 | 1 |
| 13 | 17 | 17 | 2 |
似乎正在发生的事情是,由于第 6 行更改为第 2 类,第 13 行现在位于第 2 类行的值范围内,因此也被分配为第 2 类。如何更改声明,以便 SET 仅应用于最初在范围内的值?
有关示例,请参阅demo。
【问题讨论】:
-
你的 SQLite 版本是什么?
-
版本 3.29.0(现在也包含在正文中)。
-
如果您可以升级到(至少)3.33.0,您可以使用我回答中的代码。
-
我正在研究这是否可能,但怀疑不是。我在一个预先确定的环境(QGIS 3.16,带有 python 3.7,它有一个预安装的 sqlite3 版本)中,我不能简单地改变它,而不影响我的 QGIS 插件的最终用户(谁必须做一个手动安装新版本而不是准备使用插件 - 最终用户不一定精通计算机,所以我试图避免这种情况。
-
检查我的第二个查询。
标签: sql sqlite sql-update