【发布时间】:2018-09-17 04:35:34
【问题描述】:
我有一个 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;
但现在我需要用表tmp 中的3 个参数匹配的值更新表news_article_counts 的article_count。为此,我使用以下查询(我尝试了不同的方法,但结果相同):
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 是表news_article_counts 的published_at、source、category 上的联合索引。但这不应该是一个问题,因为我没有——据我所知——更新这 3 个值中的任何一个,只更新 article_count。
最让我困惑的是,它在错误中提到了我执行查询的时间戳(这里:2018-04-07 14:46:17)。我完全不知道这在哪里起作用。事实上,news_article_counts 中的某些行现在将2018-04-07 14:46:17 作为published_at 的值。虽然这解释了错误,但我不明白为什么 published_at 会被当前时间戳覆盖。此栏目没有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;
我在这里错过了什么?
UPDATE 1:我实际上检查了数据库中news_article_counts的表定义。而且确实有以下几点:
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。我仔细检查了我的 CREATE TABLE 语句。我删除了联合索引,我添加了一个人工主键(auto_increment)。没什么帮助。我什至尝试从published_at 中明确删除这些属性:
ALTER TABLE `news_article_counts` CHANGE `published_at` `published_at` TIMESTAMP NOT NULL;
似乎没有什么对我有用。
【问题讨论】:
-
@ZamronyP.Juhara 但他没有使用那个选项。
-
这看起来很奇怪。你能在 sqlfiddle.com 上重现它吗?
-
您确定这是正确的表定义吗?上面的输出仅显示日期,但
TIMESTAMP将显示为日期和时间。
标签: mysql sql-update mysql-error-1062