为行级值引用另一个 table - 在 IF 条件下执行 INSERT INTO ... ON DUPLICATE KEY UPDATE
Reference another table for row-level values - in IF condition when doing INSERT INTO ... ON DUPLICATE KEY UPDATE
我有订单和采购。
采购有很多订单。
我正在尝试使用 ON DUPLICATE KEY UPDATE
当订单行重复时 仅当 来自购买的连接行 table 具有特定列一定的价值。
INSERT INTO `orderlines`
(col1, col2)
VALUES
('val1', 'val2')
ON DUPLICATE KEY UPDATE
col3 = IF (purchases.status_id=0, 'truevalue' , col3);
所以这个查询只处理 orderlines
table。但我想从 purchases
table 中引用 purchases.status_id
。
我不知道如何使 purchases
table 中的字段在此查询中可用。
- 我是否会在某个时候执行 LEFT JOIN?
- INSERT INTO ... SELECT 似乎不符合我要执行的操作table,因为它试图将选定的列插入 table 本身。我只想引用另一个 table 中特定行的列值,仅用于比较。
这个问题可以有一个解决方案,但是它需要我假设您的程序知道 values
提供给 INSERT
查询的内容,因此,它们是被用作变量。这只是为了确保 UDPATE
中需要的子查询可以根据需要进行控制。因此,例如 INSERT INTO orderlines (col1, col2) VALUES ('val1', 'val2') ....
。也就是说,在这种情况下,这两个变量/值在程序中都是可用的。
我们从 orderlines
table 开始(出于本次尝试的目的,id
在此处被视为 PRIMARY KEY
):
id | col1 | col2 | col3
----------------------------------------------
1 | 1 - col1 | 1 - col2 | 1 - col3
2 | 2 - col1 | 2 - col2 | 2 - col3
3 | 3 - col1 | 3 - col2 | 3 - col3
4 | 4 - col1 | 4 - col2 | 4 - col3
并定义purchases
table如下(同id
就是这里table这里的FOREIGN KEY
):
id | status_id
-----------------
1 | 0
2 | 1
从而表明 id = 1
col3
应在 orderlines
table 中更新为 truevalue
,以防 INSERT
操作遇到 DUPLICATE KEY
记录。
因此查询如下:
INSERT INTO orderlines (id, col1, col2)
VALUES (1, "1 - col1 - updated", "1 - col2 - updated")
ON DUPLICATE KEY
UPDATE
col3 = IF(
(SELECT CASE
WHEN purchases.status_id = 0 THEN "truevalue"
ELSE "falsevalue"
END AS title
FROM purchases WHERE id = 1
) = "truevalue",
"truevalue",
col3
);
(也请在查询的 INSERT
和 SELECT
部分尝试 运行 与 id = 2
进行相同的查询。
如您所见,SELECT
查询要求 与 WHERE
子句中的 相同 id
INSERT
查询 — 潜在的 DUPLICATE KEY
候选人。此查询会将 orderlines
中的 col3
更新为 id = 1
中的 truevalue
(因为其对应的 status_id
是 purchases
中的 0
table),但如果相同的查询是 运行 for id = 2
,则 col3
将保持不变。最终输出将是:
id | col1 | col2 | col3
----------------------------------------------
1 | 1 - col1 | 1 - col2 | truevalue ---> updated
2 | 2 - col1 | 2 - col2 | 2 - col3 ---> unchanged
3 | 3 - col1 | 3 - col2 | 3 - col3
4 | 4 - col1 | 4 - col2 | 4 - col3
此外,如果程序中使用了此查询,那么您还可以控制 status_id
字段的指定值。
不,您不能像您在假设解决方案中显示的那样直接在表达式中引用另一个 table。
Dhruv Saxena 的解决方案之所以有效,是因为它使用了子查询。
但是使用 INSERT...SELECT
应该更容易:
INSERT INTO `orderlines`
(order_id, col1, col2, col3)
SELECT id, 'val1', 'val2', IF(status_id=0, 'truevalue', NULL)
FROM purchases
WHERE order_id=1
ON DUPLICATE KEY UPDATE
col3 = COALESCE(VALUES(col3), col3);
仅当购买的请求行具有条件 status_id=0 时,才会为 col3 分配 'truevalue' 字符串。如果不是,则它保持 col3 不变,因为 select-列表中的 NULL 使 COALESCE() return 成为第二个参数。
我不确定我的列是否适合您的 table 关系,但此解决方案应该展示了该技术。
诀窍是对执行所需连接的重复键更新执行子查询。以下查询所做的假设是 order_id 对订单行和采购都是通用的,并且 col1 具有唯一键。
INSERT INTO `orderlines`
(col1, col2)
VALUES
('val1', 'val2')
ON DUPLICATE KEY UPDATE
col3 = (select IF(p.status_id=0, 'truevalue' , o.col3)
from orderlines o
join purchases p on p.order_id=o.order_id -- assuming this is the proper join expression between orderlines and purchases
and o.col1='val1'); -- and col1 has the unique key
我有订单和采购。 采购有很多订单。
我正在尝试使用 ON DUPLICATE KEY UPDATE
当订单行重复时 仅当 来自购买的连接行 table 具有特定列一定的价值。
INSERT INTO `orderlines`
(col1, col2)
VALUES
('val1', 'val2')
ON DUPLICATE KEY UPDATE
col3 = IF (purchases.status_id=0, 'truevalue' , col3);
所以这个查询只处理 orderlines
table。但我想从 purchases
table 中引用 purchases.status_id
。
我不知道如何使 purchases
table 中的字段在此查询中可用。
- 我是否会在某个时候执行 LEFT JOIN?
- INSERT INTO ... SELECT 似乎不符合我要执行的操作table,因为它试图将选定的列插入 table 本身。我只想引用另一个 table 中特定行的列值,仅用于比较。
这个问题可以有一个解决方案,但是它需要我假设您的程序知道 values
提供给 INSERT
查询的内容,因此,它们是被用作变量。这只是为了确保 UDPATE
中需要的子查询可以根据需要进行控制。因此,例如 INSERT INTO orderlines (col1, col2) VALUES ('val1', 'val2') ....
。也就是说,在这种情况下,这两个变量/值在程序中都是可用的。
我们从 orderlines
table 开始(出于本次尝试的目的,id
在此处被视为 PRIMARY KEY
):
id | col1 | col2 | col3
----------------------------------------------
1 | 1 - col1 | 1 - col2 | 1 - col3
2 | 2 - col1 | 2 - col2 | 2 - col3
3 | 3 - col1 | 3 - col2 | 3 - col3
4 | 4 - col1 | 4 - col2 | 4 - col3
并定义purchases
table如下(同id
就是这里table这里的FOREIGN KEY
):
id | status_id
-----------------
1 | 0
2 | 1
从而表明 id = 1
col3
应在 orderlines
table 中更新为 truevalue
,以防 INSERT
操作遇到 DUPLICATE KEY
记录。
因此查询如下:
INSERT INTO orderlines (id, col1, col2)
VALUES (1, "1 - col1 - updated", "1 - col2 - updated")
ON DUPLICATE KEY
UPDATE
col3 = IF(
(SELECT CASE
WHEN purchases.status_id = 0 THEN "truevalue"
ELSE "falsevalue"
END AS title
FROM purchases WHERE id = 1
) = "truevalue",
"truevalue",
col3
);
(也请在查询的 INSERT
和 SELECT
部分尝试 运行 与 id = 2
进行相同的查询。
如您所见,SELECT
查询要求 与 WHERE
子句中的 相同 id
INSERT
查询 — 潜在的 DUPLICATE KEY
候选人。此查询会将 orderlines
中的 col3
更新为 id = 1
中的 truevalue
(因为其对应的 status_id
是 purchases
中的 0
table),但如果相同的查询是 运行 for id = 2
,则 col3
将保持不变。最终输出将是:
id | col1 | col2 | col3
----------------------------------------------
1 | 1 - col1 | 1 - col2 | truevalue ---> updated
2 | 2 - col1 | 2 - col2 | 2 - col3 ---> unchanged
3 | 3 - col1 | 3 - col2 | 3 - col3
4 | 4 - col1 | 4 - col2 | 4 - col3
此外,如果程序中使用了此查询,那么您还可以控制 status_id
字段的指定值。
不,您不能像您在假设解决方案中显示的那样直接在表达式中引用另一个 table。
Dhruv Saxena 的解决方案之所以有效,是因为它使用了子查询。
但是使用 INSERT...SELECT
应该更容易:
INSERT INTO `orderlines`
(order_id, col1, col2, col3)
SELECT id, 'val1', 'val2', IF(status_id=0, 'truevalue', NULL)
FROM purchases
WHERE order_id=1
ON DUPLICATE KEY UPDATE
col3 = COALESCE(VALUES(col3), col3);
仅当购买的请求行具有条件 status_id=0 时,才会为 col3 分配 'truevalue' 字符串。如果不是,则它保持 col3 不变,因为 select-列表中的 NULL 使 COALESCE() return 成为第二个参数。
我不确定我的列是否适合您的 table 关系,但此解决方案应该展示了该技术。
诀窍是对执行所需连接的重复键更新执行子查询。以下查询所做的假设是 order_id 对订单行和采购都是通用的,并且 col1 具有唯一键。
INSERT INTO `orderlines`
(col1, col2)
VALUES
('val1', 'val2')
ON DUPLICATE KEY UPDATE
col3 = (select IF(p.status_id=0, 'truevalue' , o.col3)
from orderlines o
join purchases p on p.order_id=o.order_id -- assuming this is the proper join expression between orderlines and purchases
and o.col1='val1'); -- and col1 has the unique key