使用另一个表中的 COUNT/MIN/MAX 进行 mySQL 嵌套更新

发布于 2024-12-07 03:04:02 字数 1166 浏览 0 评论 0原文

我有两个大表,products(500k 记录)和 store_products(> 3mm 记录)。 Products 是主目录,product_stores 是产品的各个位置。

我需要运行一个查询来汇总来自product_stores 的信息并更新相应的产品。

当这是较小的数据集时,我们使用嵌套查询来完成:

SELECT productid,COUNT(id) as count,MIN(price) as lowprice,MAX(price) as highprice FROM store_products
WHILE (productid){ update product set stores = count, min = lowprice, max = highprice WHERE productid = $productid }
GROUP BY productid

我对嵌套更新相当陌生,并且不确定如何使用联接和分组依据设置多个字段。

结构 [截断为相关字段]:

CREATE TABLE product ( 
product_id INT UNSIGNED NOT NULL AUTO_INCREMENT,     
stores INT UNSIGNED NOT NULL DEFAULT '0',    
lowprice DECIMAL (6,2) NOT NULL DEFAULT '000.00', 
highprice  DECIMAL (6,2) NOT NULL DEFAULT '000.00', 
PRIMARY KEY (product_id), 
KEY stores (stores) 
)

CREATE TABLE store_product (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,    
product_id INT UNSIGNED NOT NULL,
price DECIMAL(7,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (storeproduct_id),
KEY product_id (product_id)
);

要更新的字段:

  • 商店 [按产品 ID 划分的 store_product 记录数]
  • 最低价格 [按产品 ID 划分的价格最小值]
  • 最高价格 [按产品 ID 划分的价格最大值]

I have two large tables, products (500k records) and store_products (> 3mm records). Products is the master and product_stores is individual locations with the product.

I need to run a single QUERY totaling up information from product_stores and updating the corresponding product.

When this was smaller dataset we did it with a nested query:

SELECT productid,COUNT(id) as count,MIN(price) as lowprice,MAX(price) as highprice FROM store_products
WHILE (productid){ update product set stores = count, min = lowprice, max = highprice WHERE productid = $productid }
GROUP BY productid

I'm fairly new to nested updates and uncertain how to set multiple fields with a join and group by.

Structure [truncated to relevant fields]:

CREATE TABLE product ( 
product_id INT UNSIGNED NOT NULL AUTO_INCREMENT,     
stores INT UNSIGNED NOT NULL DEFAULT '0',    
lowprice DECIMAL (6,2) NOT NULL DEFAULT '000.00', 
highprice  DECIMAL (6,2) NOT NULL DEFAULT '000.00', 
PRIMARY KEY (product_id), 
KEY stores (stores) 
)

CREATE TABLE store_product (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,    
product_id INT UNSIGNED NOT NULL,
price DECIMAL(7,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (storeproduct_id),
KEY product_id (product_id)
);

Fields to update:

  • stores [count of store_product records by productid]
  • min price [MIN of price by productid]
  • max price [MAX of price by productid]

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

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

发布评论

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

评论(1

空‖城人不在 2024-12-14 03:04:02

运行单个查询来对这种大小的表执行更新可能需要一段时间。无论如何 - 以下内容应该可以满足您的需求。技巧是为产品表设置别名,然后使用该别名在子查询中引用产品表。因此:

update product p 
set p.lowprice = (select min(price) from store_product sp where sp.product_id = p.product_id),
    p.highprice = (select max(price) from store_product sp where sp.product_id = p.product_id),
    p.stores = (select count(*) from store_product sp where sp.product_id = p.product_id)
where product_id in (select sp.product_id from store_product sp);

这里的一个问题是,对于 store_product 表中不存在的行,stores 列不会更新为 0。为了满足这一点,您可以使用 IFNULL 在执行全局更新时:

update product p
set lowprice = ifnull((select min(price) from store_product sp where sp.product_id = p.product_id),0),
    highprice = ifnull((select max(price) from store_product sp where sp.product_id = p.product_id),0),
    stores = ifnull((select count(*) from store_product sp where sp.product_id = p.product_id),0);

您可能想尝试两者,看看哪个更快。

希望这有帮助!

Running a single query to perform the update on tables of this size will probably take a while. Anyway - the following should give you what you need. The trick is to alias the product table and then reference the product table in the subselect using that alias. So:

update product p 
set p.lowprice = (select min(price) from store_product sp where sp.product_id = p.product_id),
    p.highprice = (select max(price) from store_product sp where sp.product_id = p.product_id),
    p.stores = (select count(*) from store_product sp where sp.product_id = p.product_id)
where product_id in (select sp.product_id from store_product sp);

One gotcha here is that the stores column will not be updated to 0 for rows that are not present in the store_product table. To cater for this you can use IFNULL while performing a global update:

update product p
set lowprice = ifnull((select min(price) from store_product sp where sp.product_id = p.product_id),0),
    highprice = ifnull((select max(price) from store_product sp where sp.product_id = p.product_id),0),
    stores = ifnull((select count(*) from store_product sp where sp.product_id = p.product_id),0);

You may want to try both out and see which is faster.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文