我可以在 MySQL 的多行更新中为 select 查询添加别名吗?
Can I alias a select query in a multiline update in MySQL?
我正在努力使这段 MySQL 代码更具可读性:
UPDATE customers
SET last_order_date = (SELECT MAX(date) FROM orders WHERE customers.customer_id = orders.customer_id),
added_note = (SELECT note FROM orders WHERE customers.customer_id = orders.customer_id
AND date = (SELECT MAX(date) FROM orders WHERE customers.customer_id = orders.customer_id));
示例代码将每个客户最近订单的日期和注释添加到客户 table 中的相应行,但它必须 SELECT
任何客户的最近订单日期给客户两次。
我尝试了建议的别名语法 here:
UPDATE customers
SET last_order_date = (SELECT MAX(date) AS `maxdate` FROM orders WHERE customers.customer_id = orders.customer_id),
added_note = (SELECT note FROM orders WHERE customers.customer_id = orders.customer_id
AND date = `maxdate`);
我也尝试过不使用 AS
关键字:
UPDATE customers
SET last_order_date = (SELECT MAX(date) maxdate FROM orders WHERE customers.customer_id = orders.customer_id),
added_note = (SELECT note FROM orders WHERE customers.customer_id = orders.customer_id
AND date = maxdate);
但在这两种情况下都无法识别别名。
有没有一种方法可以将中间结果分配给一个名称并在以后引用它?
对于 MySQL 8.0,您可以使用 CTE:
WITH o AS (
SELECT date, note, customer_id,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY date DESC) AS rownum
FROM orders
)
UPDATE customers AS c
INNER JOIN o USING (customer_id)
SET c.last_order_date = o.date,
c.added_note = o.note
WHERE o.rownum = 1;
对于不支持 CTE 的 MySQL 旧版本,以下是我的编码方式:
UPDATE customers AS c
INNER JOIN orders AS o1
ON c.customer_id=o1.customer_id
LEFT OUTER JOIN orders AS o2
ON o1.customer_id=o2.customer_id AND o1.date < o2.date
SET c.last_order_date = o1.date,
c.added_note = o1.note
WHERE o2.customer_id IS NULL;
外连接 returns 当没有匹配时,连接的所有列都为 NULL table。如果没有行 o2
的日期大于行 o1
,则 o1
必须是相应 customer_id.
的日期最大的行
后一种解决方案可能会导致平局。也就是说,可能有不止一行与给定客户的最大日期相关联。 CTE 解决方案不会有这个问题。
我正在努力使这段 MySQL 代码更具可读性:
UPDATE customers
SET last_order_date = (SELECT MAX(date) FROM orders WHERE customers.customer_id = orders.customer_id),
added_note = (SELECT note FROM orders WHERE customers.customer_id = orders.customer_id
AND date = (SELECT MAX(date) FROM orders WHERE customers.customer_id = orders.customer_id));
示例代码将每个客户最近订单的日期和注释添加到客户 table 中的相应行,但它必须 SELECT
任何客户的最近订单日期给客户两次。
我尝试了建议的别名语法 here:
UPDATE customers
SET last_order_date = (SELECT MAX(date) AS `maxdate` FROM orders WHERE customers.customer_id = orders.customer_id),
added_note = (SELECT note FROM orders WHERE customers.customer_id = orders.customer_id
AND date = `maxdate`);
我也尝试过不使用 AS
关键字:
UPDATE customers
SET last_order_date = (SELECT MAX(date) maxdate FROM orders WHERE customers.customer_id = orders.customer_id),
added_note = (SELECT note FROM orders WHERE customers.customer_id = orders.customer_id
AND date = maxdate);
但在这两种情况下都无法识别别名。
有没有一种方法可以将中间结果分配给一个名称并在以后引用它?
对于 MySQL 8.0,您可以使用 CTE:
WITH o AS (
SELECT date, note, customer_id,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY date DESC) AS rownum
FROM orders
)
UPDATE customers AS c
INNER JOIN o USING (customer_id)
SET c.last_order_date = o.date,
c.added_note = o.note
WHERE o.rownum = 1;
对于不支持 CTE 的 MySQL 旧版本,以下是我的编码方式:
UPDATE customers AS c
INNER JOIN orders AS o1
ON c.customer_id=o1.customer_id
LEFT OUTER JOIN orders AS o2
ON o1.customer_id=o2.customer_id AND o1.date < o2.date
SET c.last_order_date = o1.date,
c.added_note = o1.note
WHERE o2.customer_id IS NULL;
外连接 returns 当没有匹配时,连接的所有列都为 NULL table。如果没有行 o2
的日期大于行 o1
,则 o1
必须是相应 customer_id.
后一种解决方案可能会导致平局。也就是说,可能有不止一行与给定客户的最大日期相关联。 CTE 解决方案不会有这个问题。