根据值的范围更新行,而不更改最初不在范围内的行
Update rows based on range around values without changing rows that are not initially within range
在本地 SQLite (vs 3.29.0) 数据库中,有一个 table 有 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.33.0+,您可以使用类似连接的 UPDATE...FROM
语法在 UPDATE
语句中执行自连接:
UPDATE tablename AS t1
SET Category = t2.Category
FROM tablename AS t2
WHERE t2.Category = 2
AND t1.Category <> t2.Category
AND t1.Value BETWEEN t2.Value - 4 AND t2.Value + 4
AND t1.Value2 BETWEEN t2.Value2 - 2 AND t2.Value2 + 2;
对于以前版本的 SQLite,首先创建一个临时 table,其中包含 table 和 Category = 2
的所有行:
CREATE TEMPORARY TABLE t AS
SELECT * FROM tablename WHERE Category = 2;
然后更新 table:
UPDATE tablename
SET Category = 2
WHERE Category <> 2
AND EXISTS (
SELECT 1
FROM t
WHERE tablename.Value BETWEEN t.Value - 4 AND t.Value + 4
AND tablename.Value2 BETWEEN t.Value2 -2 AND t.Value2 + 2
);
参见demo。
在本地 SQLite (vs 3.29.0) 数据库中,有一个 table 有 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.33.0+,您可以使用类似连接的 UPDATE...FROM
语法在 UPDATE
语句中执行自连接:
UPDATE tablename AS t1
SET Category = t2.Category
FROM tablename AS t2
WHERE t2.Category = 2
AND t1.Category <> t2.Category
AND t1.Value BETWEEN t2.Value - 4 AND t2.Value + 4
AND t1.Value2 BETWEEN t2.Value2 - 2 AND t2.Value2 + 2;
对于以前版本的 SQLite,首先创建一个临时 table,其中包含 table 和 Category = 2
的所有行:
CREATE TEMPORARY TABLE t AS
SELECT * FROM tablename WHERE Category = 2;
然后更新 table:
UPDATE tablename
SET Category = 2
WHERE Category <> 2
AND EXISTS (
SELECT 1
FROM t
WHERE tablename.Value BETWEEN t.Value - 4 AND t.Value + 4
AND tablename.Value2 BETWEEN t.Value2 -2 AND t.Value2 + 2
);
参见demo。