0

我的表存储我的 CMS 条目的修订数据。每个条目都有一个 ID 和一个修订日期,并且有多个修订:

Table: old_revisions
+----------+---------------+-----------------------------------------+
| entry_id | revision_date |               entry_data                |
+----------+---------------+-----------------------------------------+
|        1 |    1302150011 | I like pie.                             |
|        1 |    1302148411 | I like pie and cookies.                 |
|        1 |    1302149885 | I like pie and cookies and cake.        |
|        2 |    1288917372 | Kittens are cute.                       |
|        2 |    1288918782 | Kittens are cute but puppies are cuter. |
|        3 |    1288056095 | Han shot first.                         |
+----------+---------------+-----------------------------------------+

我想将其中一些数据传输到另一个表:

Table: new_revisions
+--------------+----------------+
| new_entry_id | new_entry_data |
+--------------+----------------+
|              |                |
+--------------+----------------+

我想将entry_idand转移entry_datanew_entry_idand new_entry_data。但我只想传输每个条目的最新版本。

我得到了这个查询:

INSERT INTO new_revisions (
    new_entry_id,
    new_entry_data
)
SELECT
entry_id,
entry_data,
MAX(revision_date)
FROM old_revisions
GROUP BY entry_id

但我认为问题在于我试图将 3 列数据插入 2 列。

如何在不传输修订日期的情况下根据修订日期传输数据?

4

2 回答 2

3

您可以使用以下查询:

insert into new_revisions (new_entry_id, new_entry_data)
select o1.entry_id, o1.entry_data
from old_revisions o1
inner join
(
  select max(revision_date) maxDate, entry_id
  from old_revisions
  group by entry_id
) o2
  on o1.entry_id = o2.entry_id
  and o1.revision_date = o2.maxDate

请参阅SQL Fiddle with Demo。此查询获取max(revision_date)for each entry_id,然后在 the 和 max 日期连接回您的表entry_id以获取要插入的行。

请注意,子查询仅返回entry_id日期和日期,这是因为我们希望将 应用于GROUP BY选择列表中不在聚合函数中的项目。MySQL 使用对GROUP BY子句的扩展,允许选择列表中的列被排除在 group by 和聚合中,但这可能会导致意外结果。通过仅包括聚合所需的列和分组依据将确保结果是您想要的值。(参见MySQL 对 GROUP BY 的扩展

来自 MySQL 文档:

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。...您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。在选择了值之后对结果集进行排序,并且 ORDER BY 不会影响服务器选择的值。

于 2013-04-03T22:14:33.767 回答
2

如果要输入最后一个条目,则需要先对其进行过滤:

select entry_id, max(revision_date) as maxDate
from old_revisions
group by entry_id;

然后将其用作子查询来过滤您需要的数据:

insert into new_revisions (new_entry_id, new_entry_data)
select entry_id, entry_data
from old_revisions as o
    inner join (
        select entry_id, max(revision_date) as maxDate
        from old_revisions
        group by entry_id
    ) as a on o.entry_id = a.entry_id and o.revision_date = a.maxDate
于 2013-04-03T22:15:31.567 回答