8

如果您必须选择以下两个查询之一,您会选择哪个以及为什么:

UPDATE `table1` AS e
SET e.points = e.points+(
SELECT points FROM `table2` AS ep WHERE e.cardnbr=ep.cardnbr);

或者:

UPDATE `table1` AS e
INNER JOIN
(
   SELECT points, cardnbr
   FROM `table2`  
) AS ep ON (e.cardnbr=ep.cardnbr)
SET e.points = e.points+ep.points;

表的定义:

CREATE TABLE `table1` (
  `cardnbr` int(10) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `points` decimal(7,3) DEFAULT '0.000',
  `email` varchar(50) NOT NULL DEFAULT 'user@company.com',
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=25205 DEFAULT CHARSET=latin1$$

CREATE TABLE `table2` (
  `cardnbr` int(10) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `points` decimal(7,3) DEFAULT '0.000',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci$$

更新:两者都导致问题首先是导致不匹配的行更新为 NULL。第二个是使它们更新为最大值 999.9999(十进制 7,3)。PS cardnbr 字段不是键

4

2 回答 2

2

我更喜欢第二个..原因是

使用JOIN数据库时,可以创建一个更适合您的查询并节省时间的执行计划,而子查询(如您的第一个)将运行所有查询并加载所有可能需要时间的数据。

我认为子查询很容易阅读,但性能方面JOIN更快......

于 2013-02-05T07:43:15.847 回答
1

首先,正如您自己发现的那样,这两个陈述并不等同。第一个将更新 的所有行table1,将NULL那些没有相关行的行的值放入table2.

所以第二个查询看起来更好,因为它不会更新table1. 它可以以更简单的方式编写,但如下所示:

UPDATE table1 AS e
  INNER JOIN table2 AS ep
      ON e.cardnbr = ep.cardnbr
SET e.points = e.points + ep.points ;

因此,第二个查询将是最好使用的,如果cardnbrtable2. 是吗?

如果不是,那么 table2 中的哪些值应该用于更新 table1(添加到points)?他们都是?你可以使用这个:

UPDATE table1 AS e
  INNER JOIN
  (  SELECT SUM(points) AS points, cardnbr
     FROM table2  
     GROUP BY cardnbr
  ) AS ep ON e.cardnbr = ep.cardnbr
SET 
    e.points = e.points + ep.points ;

只有其中之一?这将需要一些其他派生表,具体取决于您想要什么。

于 2013-02-05T09:13:08.607 回答