MySQL,用一个查询更新多个表

发布于 2024-10-06 11:41:40 字数 87 浏览 3 评论 0原文

我有一个更新三个表的函数,但我使用三个查询来执行此操作。我希望使用更方便的方法来进行良好的实践。

如何使用单个查询更新 MySQL 中的多个表?

I have a function that updates three tables, but I use three queries to perform this. I wish to use a more convenient approach for good practice.

How can I update multiple tables in MySQL with a single query?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

爱已欠费 2024-10-13 11:41:40

以两个表为例:BooksOrders。如果我们在 Orders 表中使用 Order.ID = 1002 增加特定订单中的图书数量,那么我们还需要减少我们的库存在 Books 表中具有相同的编号。

UPDATE Books, Orders
SET Orders.Quantity = Orders.Quantity + 2,
    Books.InStock = Books.InStock - 2
WHERE
    Books.BookID = Orders.BookID
    AND Orders.OrderID = 1002;

Take the case of two tables, Books and Orders. In case, we increase the number of books in a particular order with Order.ID = 1002 in Orders table then we also need to reduce that the total number of books available in our stock by the same number in Books table.

UPDATE Books, Orders
SET Orders.Quantity = Orders.Quantity + 2,
    Books.InStock = Books.InStock - 2
WHERE
    Books.BookID = Orders.BookID
    AND Orders.OrderID = 1002;
我喜欢麦丽素 2024-10-13 11:41:40
UPDATE t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
SET t1.a = 'something',
    t2.b = 42,
    t3.c = t2.c
WHERE t1.a = 'blah';

要查看要更新的内容,您可以将其转换为选择语句,例如:

SELECT t2.t1_id, t2.t3_id, t1.a, t2.b, t2.c AS t2_c, t3.c AS t3_c
FROM t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
WHERE t1.a = 'blah';

使用与其他答案相同的表的示例:

SELECT Books.BookID, Orders.OrderID,
    Orders.Quantity AS CurrentQuantity,
    Orders.Quantity + 2 AS NewQuantity,
    Books.InStock AS CurrentStock,
    Books.InStock - 2 AS NewStock
FROM Books
INNER JOIN Orders ON Books.BookID = Orders.BookID
WHERE Orders.OrderID = 1002;

UPDATE Books
INNER JOIN Orders ON Books.BookID = Orders.BookID
SET Orders.Quantity = Orders.Quantity + 2,
    Books.InStock = Books.InStock - 2
WHERE Orders.OrderID = 1002;

编辑:

只是为了好玩,让我们添加一些更有趣的内容。

假设您有一个书籍表和一个作者表。您的图书有一个author_id。但最初创建数据库时,没有设置外键约束,后来前端代码的一个错误导致一些书籍添加了无效的author_id。作为 DBA,您不想通过所有这些书籍来检查 author_id 应该是什么,因此决定数据捕获器将修复books 指向正确的作者。但是书籍太多,无法逐一浏览,假设您知道那些具有与实际 author 相对应的 author_id 的书籍是正确的。只有 author_id 不存在的那些才是无效的。已经有一个接口供用户更新书籍详细信息,并且开发人员不想仅仅因为这个问题而更改该接口。但现有的接口会进行INNER JOIN Authors,因此所有具有无效作者的书籍都被排除在外。

你可以做的是:插入一个假作者记录,如“未知作者”。然后更新所有不良记录的author_id以指向未知作者。然后数据捕获器可以搜索作者设置为“未知作者”的所有书籍,查找正确的作者并修复它们。

如何更新所有不良记录以指向未知作者?像这样(假设未知作者的 author_id 为 99999):

UPDATE books
LEFT OUTER JOIN authors ON books.author_id = authors.id
SET books.author_id = 99999
WHERE authors.id IS NULL;

以上还将更新具有 NULL author_idbooks > 致未知作者。如果您不希望这样,当然可以添加AND books.author_id IS NOT NULL

UPDATE t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
SET t1.a = 'something',
    t2.b = 42,
    t3.c = t2.c
WHERE t1.a = 'blah';

To see what this is going to update, you can convert this into a select statement, e.g.:

SELECT t2.t1_id, t2.t3_id, t1.a, t2.b, t2.c AS t2_c, t3.c AS t3_c
FROM t1
INNER JOIN t2 ON t2.t1_id = t1.id
INNER JOIN t3 ON t2.t3_id = t3.id
WHERE t1.a = 'blah';

An example using the same tables as the other answer:

SELECT Books.BookID, Orders.OrderID,
    Orders.Quantity AS CurrentQuantity,
    Orders.Quantity + 2 AS NewQuantity,
    Books.InStock AS CurrentStock,
    Books.InStock - 2 AS NewStock
FROM Books
INNER JOIN Orders ON Books.BookID = Orders.BookID
WHERE Orders.OrderID = 1002;

UPDATE Books
INNER JOIN Orders ON Books.BookID = Orders.BookID
SET Orders.Quantity = Orders.Quantity + 2,
    Books.InStock = Books.InStock - 2
WHERE Orders.OrderID = 1002;

EDIT:

Just for fun, let's add something a bit more interesting.

Let's say you have a table of books and a table of authors. Your books have an author_id. But when the database was originally created, no foreign key constraints were set up and later a bug in the front-end code caused some books to be added with invalid author_ids. As a DBA you don't want to have to go through all of these books to check what the author_id should be, so the decision is made that the data capturers will fix the books to point to the right authors. But there are too many books to go through each one and let's say you know that the ones that have an author_id that corresponds with an actual author are correct. It's just the ones that have nonexistent author_ids that are invalid. There is already an interface for the users to update the book details and the developers don't want to change that just for this problem. But the existing interface does an INNER JOIN authors, so all of the books with invalid authors are excluded.

What you can do is this: Insert a fake author record like "Unknown author". Then update the author_id of all the bad records to point to the Unknown author. Then the data capturers can search for all books with the author set to "Unknown author", look up the correct author and fix them.

How do you update all of the bad records to point to the Unknown author? Like this (assuming the Unknown author's author_id is 99999):

UPDATE books
LEFT OUTER JOIN authors ON books.author_id = authors.id
SET books.author_id = 99999
WHERE authors.id IS NULL;

The above will also update books that have a NULL author_id to the Unknown author. If you don't want that, of course you can add AND books.author_id IS NOT NULL.

时光沙漏 2024-10-13 11:41:40

您也可以使用像这样的联接来通过一个查询来完成此操作:

UPDATE table1,table2 SET table1.col=a,table2.col2=b
WHERE items.id=month.id;

当然,然后只需发送这个查询。您可以在此处阅读有关联接的更多信息: http://dev.mysql.com /doc/refman/5.0/en/join.html。对于多个表更新的排序和限制还有一些限制,您可以在此处阅读:http://dev.mysql.com/doc/refman/5.0/en/update.html(只需 ctrl+f“加入”)。

You can also do this with one query too using a join like so:

UPDATE table1,table2 SET table1.col=a,table2.col2=b
WHERE items.id=month.id;

And then just send this one query, of course. You can read more about joins here: http://dev.mysql.com/doc/refman/5.0/en/join.html. There's also a couple restrictions for ordering and limiting on multiple table updates you can read about here: http://dev.mysql.com/doc/refman/5.0/en/update.html (just ctrl+f "join").

仙女 2024-10-13 11:41:40

这通常就是存储过程的用途:按顺序执行多个 SQL 语句。使用回滚,您可以确保将它们视为一个工作单元,即它们要么全部执行,要么都不执行,以保持数据一致。

That's usually what stored procedures are for: to implement several SQL statements in a sequence. Using rollbacks, you can ensure that they are treated as one unit of work, ie either they are all executed or none of them are, to keep data consistent.

残月升风 2024-10-13 11:41:40

当您说多个查询时,您的意思是多个 SQL 语句,如:

UPDATE table1 SET a=b WHERE c;
UPDATE table2 SET a=b WHERE d;
UPDATE table3 SET a=b WHERE e;

或多个查询函数调用,如:

mySqlQuery(UPDATE table1 SET a=b WHERE c;)
mySqlQuery(UPDATE table2 SET a=b WHERE d;)
mySqlQuery(UPDATE table3 SET a=b WHERE e;)

前者都可以使用单个 mySqlQuery 调用来完成,如果这是您想要实现的,只需调用下面的 mySqlQuery 函数方式:

mySqlQuery(UPDATE table1 SET a=b WHERE c; UPDATE table2 SET a=b WHERE d; UPDATE table3 SET a=b WHERE e;)

这将通过一次 mySqlQuery() 调用执行所有三个查询。

When you say multiple queries do you mean multiple SQL statements as in:

UPDATE table1 SET a=b WHERE c;
UPDATE table2 SET a=b WHERE d;
UPDATE table3 SET a=b WHERE e;

Or multiple query function calls as in:

mySqlQuery(UPDATE table1 SET a=b WHERE c;)
mySqlQuery(UPDATE table2 SET a=b WHERE d;)
mySqlQuery(UPDATE table3 SET a=b WHERE e;)

The former can all be done using a single mySqlQuery call if that is what you wanted to achieve, simply call the mySqlQuery function in the following manner:

mySqlQuery(UPDATE table1 SET a=b WHERE c; UPDATE table2 SET a=b WHERE d; UPDATE table3 SET a=b WHERE e;)

This will execute all three queries with one mySqlQuery() call.

触ぅ动初心 2024-10-13 11:41:40

假设我有 Table1 ,其中包含主键 _id 和布尔列 doc_availabilityTable2 具有外键 _id 和 DateTime 列 last_update,我想更改 _id 14 文档的可用性将 Table1 中的值设置为 0,即不可用,并使用文档上次更新时的时间戳更新 Table2。以下查询将完成该任务:

UPDATE Table1, Table2 
SET doc_availability = 0, last_update = NOW() 
WHERE Table1._id = Table2._id AND Table1._id = 14

Let's say I have Table1 with primary key _id and a boolean column doc_availability; Table2 with foreign key _id and DateTime column last_update and I want to change the availability of a document with _id 14 in Table1 to 0 i.e unavailable and update Table2 with the timestamp when the document was last updated. The following query would do the task:

UPDATE Table1, Table2 
SET doc_availability = 0, last_update = NOW() 
WHERE Table1._id = Table2._id AND Table1._id = 14
旧竹 2024-10-13 11:41:40
let id = req.params.id;
let pname = req.body.pname;
let catname = req.body.catname;
let scatname = req.body.scatname;
let price = req.body.price;
let available_qty = req.body.available_qty

'更新产品、类别、子类别设置category.name=?,subcategoey.name=?, products.name=?, products.price=?, products.available_qty=? WHERE Category.id= subcategoey.cid AND subcategoey.id = products.scid AND products.id=?',[catname,scatname,pname,price,available_qty,id],

它对我有用...

let id = req.params.id;
let pname = req.body.pname;
let catname = req.body.catname;
let scatname = req.body.scatname;
let price = req.body.price;
let available_qty = req.body.available_qty

'UPDATE products,category,subcategoey set category.name=?,subcategoey.name=?, products.name=?, products.price=?, products.available_qty=? WHERE category.id= subcategoey.cid AND subcategoey.id = products.scid AND products.id=?',[catname,scatname,pname,price,available_qty,id],

it works for me...

烟凡古楼 2024-10-13 11:41:40

问题已经得到解答,但还有一件事需要注意。

JOIN 查询必须位于 SET 查询之前

这将起作用

UPDATE post p
JOIN user u ON p.user_id = u.id
SET p.is_deleted = 1, u.state = "disabled"  
WHERE u.email = '[email protected]'

这将不起作用

UPDATE post p
SET p.is_deleted = 1, u.state = "disabled" 
JOIN user u ON p.user_id = u.id 
WHERE u.email = '[email protected]'

The question is already answered but there is one thing to take care of.

The JOIN query must be before the SET query

This will work

UPDATE post p
JOIN user u ON p.user_id = u.id
SET p.is_deleted = 1, u.state = "disabled"  
WHERE u.email = '[email protected]'

This will NOT work

UPDATE post p
SET p.is_deleted = 1, u.state = "disabled" 
JOIN user u ON p.user_id = u.id 
WHERE u.email = '[email protected]'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文