MySQL:UPDATE查询的奇怪行为(ERROR 1062重复条目)

时间:2018-04-07 07:00:43

标签: mysql sql-update mysql-error-1062

我有一个MySQL数据库,存储新闻文章,包括出版日期(仅日信息),来源和类别。基于这些我想生成一个表格,其中包含文章计数w.r.t.这3个参数。

由于这三个参数的某些组合可能没有文章,因此简单的GROUP BY不会。因此,我首先生成一个表news_article_counts,其中包含3个参数的所有可能组合,默认article_count为0 - 如下所示:

SELECT * FROM news_article_counts;
+--------------+------------+----------+---------------+
| published_at | source     | category | article_count |
+------------- +------------+----------+---------------+
| 2016-08-05   | 1826089206 |        0 |             0 |
| 2016-08-05   | 1826089206 |        1 |             0 |
| 2016-08-05   | 1826089206 |        2 |             0 |
| 2016-08-05   | 1826089206 |        3 |             0 |
| 2016-08-05   | 1826089206 |        4 |             0 |
| ...          | ...        |      ... |           ... |
+--------------+------------+----------+---------------+

为了进行测试,我现在创建了一个临时表tmp作为原始新闻文章表中的GROUP BY结果:

SELECT * FROM tmp LIMIT 6;
+--------------+------------+----------+-----+
| published_at | source     | category | cnt |
+--------------+------------+----------+-----+
| 2016-08-05   | 1826089206 |        3 |   1 |
| 2003-09-19   | 1826089206 |        4 |   1 |
| 2005-08-08   | 1826089206 |        3 |   1 |
| 2008-07-22   | 1826089206 |        4 |   1 |
| 2008-11-26   | 1826089206 |        8 |   1 |
| ...          | ...        |      ... | ... |
+--------------+------------+----------+-----+

鉴于这两个表,以下查询按预期工作:

SELECT * FROM news_article_counts c, tmp t
WHERE c.published_at = t.published_at AND c.source = t.source AND c.category = t.category;

但现在我需要使用表article_count中与3个参数匹配的值更新表news_article_counts的{​​{1}}。为此,我使用以下查询(我尝试了不同的方法,但结果相同):

tmp

执行此查询会产生此错误:

UPDATE 
  news_article_counts c
INNER JOIN
  tmp t
ON
  c.published_at = t.published_at AND
  c.source = t.source AND
  c.category = t.category
SET
  c.article_count = t.cnt;

ERROR 1062 (23000): Duplicate entry '2018-04-07 14:46:17-1826089206-1' for key 'uniqueIndex' 是表uniqueIndex的{​​{1}},published_atsource的联合索引。但这应该不是问题,因为我没有 - 据我所知 - 更新这3个值中的任何一个,只有category

最让我困惑的是,在错误中它提到了我执行查询的时间戳(这里:news_article_counts)。我不知道这会发挥作用。实际上,article_count中的某些行现在具有2018-04-07 14:46:17作为news_article_counts的值。虽然这解释了错误,但我看不出为什么2018-04-07 14:46:17会被当前时间戳覆盖。此列中没有published_at;见:

published_at

我在这里缺少什么?

UPDATE 1 :我实际检查了数据库中ON UPDATE CURRENT_TIMESTAMP的表定义。确实存在以下情况:

CREATE TABLE IF NOT EXISTS `test`.`news_article_counts` (
  `published_at` TIMESTAMP NOT NULL,
  `source` INT UNSIGNED NOT NULL,
  `category` INT UNSIGNED NOT NULL,
  `article_count` INT UNSIGNED NOT NULL DEFAULT 0,
  UNIQUE INDEX `uniqueIndex` (`published_at` ASC, `source` ASC, `category`  ASC))
ENGINE = MyISAM
DEFAULT CHARACTER SET = utf8mb4;

但为什么设置news_article_counts。我对我的CREATE TABLE语句进行了双重和三重检查。我删除了联合索引,我添加了一个人工主键(auto_increment)。什么都没有帮助。我甚至尝试使用以下内容从mysql> SHOW COLUMNS FROM news_article_counts; +---------------+------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +---------------+------------------+------+-----+-------------------+-----------------------------+ | published_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | | source | int(10) unsigned | NO | | NULL | | | category | int(10) unsigned | NO | | NULL | | | article_count | int(10) unsigned | NO | | 0 | | +---------------+------------------+------+-----+-------------------+-----------------------------+ 明确删除这些属性:

on update CURRENT_TIMESTAMP

似乎没有什么对我有用。

1 个答案:

答案 0 :(得分:1)

看起来您已禁用explicit_defaults_for_timestamp系统变量。其中一个影响是:

  

如果未使用TIMESTAMP属性或显式NULLDEFAULT属性显式声明,表中的第一个ON UPDATE列会自动声明为{{ 1}}和DEFAULT CURRENT_TIMESTAMP属性。

您可以尝试启用此系统变量,但这可能会影响其他应用程序。我认为它只会在您实际创建表格时生效,因此它不应影响任何现有表格。

如果您没有像这样进行系统级更改,可以在此表的ON UPDATE CURRENT_TIMESTAMP列中添加明确的DEFAULT属性,然后它就会赢了自动添加published_at