【发布时间】:2021-05-03 21:40:54
【问题描述】:
我正在尝试将相似值 (val1,val2) 的命中计数保持在指定阈值(±某个值)内。
对于完全匹配,我会使用 UPSERT,但我不知道如何使它适用于类似的匹配。
给定一张桌子valuetable
| id | val1 | val2 | count |
|---|---|---|---|
| 1 | 1.1 | 2.2 | 2 |
| 2 | 1.7 | 2.2 | 1 |
| 3 | 1.0 | 2.2 | 1 |
我们应该这样做
INSERT INTO valuetable
VALUES(DEFAULT, 1.2, 2.1, 1)
ON CONFLICT (val1 ± 0.1,val2 ± 0.1)
DO
UPDATE SET count = count + 1
我们将得到下表,其中id=1 的count 递增,因为val1 和val2 的id=1 在指定的0.1 范围内。
| id | val1 | val2 | count |
|---|---|---|---|
| 1 | 1.1 | 2.2 | 3 |
| 2 | 1.7 | 2.2 | 1 |
| 3 | 1.0 | 2.2 | 1 |
如果可能的话,还有另一个问题。
如果我们要进行下面的查询,id=1 和 id=3 都符合条件。
INSERT INTO valuetable
VALUES(DEFAULT, 1.0, 2.1, 1)
ON CONFLICT (val1 ± 0.1,val2 ± 0.1)
DO
UPDATE SET count = count + 1
我们如何更新具有最高(或最低)count 的那个(例如,id=1 得到更新,因为它在所有匹配行中具有最高的 count,共 2 个)?
| id | val1 | val2 | count |
|---|---|---|---|
| 1 | 1.1 | 2.2 | 3 |
| 2 | 1.7 | 2.2 | 1 |
| 3 | 1.0 | 2.2 | 1 |
或更新净差最小(或最大)的那个(例如 id=3 得到更新,因为它的净差为 0.1 而不是 id=1 0.2)?
| id | val1 | val2 | count |
|---|---|---|---|
| 1 | 1.1 | 2.2 | 2 |
| 2 | 1.7 | 2.2 | 1 |
| 3 | 1.0 | 2.2 | 2 |
注意:有过标准化值的想法,例如0.1, 0.2, ...,因此可以进行精确匹配,
但最好不要诉诸于此,因为0.1, 0.2, ... 的阈值为0.5 仍然会遇到同样的问题,而0.5, 1.0, ... 会丢失太多上下文。
【问题讨论】:
标签: sql postgresql insert-update postgresql-9.5 upsert