通过将它们合并为一个来加速以下查询

时间:2014-10-13 08:45:44

标签: mysql sql

我需要找到一种方法将两个查询合并为一个。

这是我正在使用的表格的结构: (还有其他关于内容和评级的字段,但我没有添加它们,因为它们并不需要。

-- Create syntax for TABLE 'contents'
CREATE TABLE `contents` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `rating` decimal(5,4) DEFAULT '0.0000',
  `ratingsCount` int(8) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- Create syntax for TABLE 'ratings'
CREATE TABLE `ratings` (
  `what` int(11) DEFAULT NULL,
  `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `rating` decimal(3,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

自从我上次询问有关堆栈溢出的内容后,有人告诉我要编写我现在正在使用的代码。这是:

db.query("SELECT AVG(rating) `avg`, COUNT(rating) cnt FROM `ratings` WHERE what = ?", [req.params.id], function(err, avg) {
    db.query("UPDATE contents SET `rating` = ?, `ratingsCount` = ? WHERE id = ?", [avg[0].avg, avg[0].cnt, req.params.id], function() { });
});

2 个答案:

答案 0 :(得分:2)

您可以使用UPDATE / JOIN组合在数据库的单次往返中执行此操作;

UPDATE contents c 
JOIN (
  SELECT what, AVG(rating) rating, COUNT(rating) ratingsCount
  FROM ratings WHERE what = ? GROUP BY what
) r
  ON c.id = r.what
SET c.rating = r.rating, c.ratingsCount = r.ratingsCount

An SQLfiddle to test with

子查询将找到“what”值的平均值/计数,外部查询将加入该信息以更新contents

答案 1 :(得分:0)

这个人会做的工作:

UPDATE contents c SET
   rating=(SELECT AVG(rating) FROM ratings r WHERE r.what=c.id),
   ratingsCount=(SELECT COUNT(rating) FROM ratings r WHERE r.what=c.id);

您需要为idwhat列添加索引。