我的表values
包含这样的列:
id: integer primary key
value: varchar(128)
type_id: integer (foreign key)
owner_id: integer (foreign key)
以及一些示例数据:
id value type_id owner_id
...
5 aaa 0 1
6 bbb 0 2 // Rows
7 ccc 1 2 // to
8 ddd 1 2 // be
9 eee 2 2 // replaced
10 fff 0 3
...
现在我想用一组新数据替换owner_id
== 2的所有行。简单方法是DELETE
== 2和owner_id
新行的所有行INSERT
。不过我想知道是否还有其他解决方案?
就我而言:
bbb
type_id
== 0 bbb
,ccc
,ddd
和eee
的{{1}}加type_id
ggg
= 1的值完全相同type_id
列中的某个值已更改(需要更新)。示例:完全相同的数据,而不是values
ccc
== 1,type_id
ggg
== 1 我试图避免type_id
+ DELETE
我会有很多此类更新并使用此类方法INSERT
的原因将开始快速增长。
答案 0 :(得分:1)
由于您似乎没有回应评论,让我们开始吧 根据我上面的评论,我做了一些皱纹(看起来像我)的一些皱纹:
CREATE UNIQUE INDEX ValuesTable_TypeOwner ON ValuesTable(owner_id, type_id);
注意:我更改了表名,因为 VALUES 是一个SQL保留字。
您可能想要尝试(从名为更改的表中提取应用修改):
WITH
To_Delete (id) AS (
SELECT
id
FROM ValuesTable V
JOIN Changes C
ON V.owner_id = C.owner_id
AND V.type_id
NOT IN (SELECT type_id
FROM Changes
WHERE owner_id = C.owner_id)
)
DELETE FROM ValuesTable
WHERE id IN (SELECT id FROM To_Delete)
;
WITH
To_Update (id) AS (
SELECT
id
FROM ValuesTable V
JOIN Changes C
ON V.owner_id = C.owner_id
AND V.type_id = C.type_id
AND V.value <> C.value
)
UPDATE ValuesTable
SET value = (SELECT value
FROM Changes
WHERE ValuesTable.owner_id = owner_id
AND ValuesTable.type_id = type_id
)
WHERE id IN (SELECT id FROM To_Update)
;
WITH
To_Insert (value, type_id, owner_id) AS (
SELECT
value
, type_id
, owner_id
FROM Changes
WHERE NOT EXISTS
(SELECT 1
FROM ValuesTable
WHERE Changes.owner_id = owner_id
AND Changes.type_id = type_id
)
)
INSERT INTO ValuesTable (value, type_id, owner_id)
SELECT value, type_id, owner_id FROM To_Insert
;
从
开始ValuesTable Changes
| id | value | type_id | owner_id | | value | type_id | owner_id |
|----|-------|---------|----------| |-------|---------|----------|
| 5 | aaa | 0 | 1 | | ccc | 1 | 2 |
| 6 | bbb | 0 | 2 | | ddd | 2 | 2 |
| 7 | ccc | 1 | 2 | | xxx | 3 | 2 |
| 8 | ddd | 2 | 2 | | yyy | 4 | 2 |
| 9 | eee | 3 | 2 |
| 10 | fff | 0 | 3 |
它返回:
| id | value | type_id | owner_id |
|----|-------|---------|----------|
| 5 | aaa | 0 | 1 |
| 7 | ccc | 1 | 2 |
| 8 | ddd | 2 | 2 |
| 9 | xxx | 3 | 2 |
| 11 | yyy | 4 | 2 |
| 10 | fff | 0 | 3 |
查看实际操作:SQL Fiddle。
注意:当然,WITH
子句可以相应地扩展,而不是使用更改表。
请评论是否需要调整/进一步详细说明。