【问题标题】:How do I get a subquery to be updated for each row inserted in mysql?如何为插入 mysql 的每一行更新子查询?
【发布时间】:2012-04-30 19:10:39
【问题描述】:

我的查询如下所示:

INSERT INTO table1 (lfd, somedata)
select (select max(lfd) + 1 from table1), somedata from table2

Table2 有多行。所以我想将多行插入table1。 这可行,但 lfd 为所有插入的行设置为相同的数字。

因此,如果插入的第一行的 max(ldf) + 1 为“2”,那么接下来的所有行也为“2”。这是不正确的,因为下一行的 max(lfd) + 1 当然应该返回“3”。

我如何告诉 mysql 重新评估每个插入的子查询?

我无法触摸表结构,因为我将数据从一个 php-gallery 迁移到另一个不同的 php-gallery。表的结构由应用程序控制。

在 Oracle 中,我只需定义一个序列并在子选择中选择 squeencename.nextval。 - 我很确定这会起作用,但据我所知,mysql 不提供序列,对吧?

【问题讨论】:

  • 和答案一样,同样的问题:我不能碰桌子结构。
  • 您可能会以任何其他方式面临并发问题(除非您锁定表) - 是否有可能其他用户/连接也可能在您的查询时将新记录插入table1 表跑步吗?

标签: mysql insert max subquery


【解决方案1】:

试试这个:

SELECT MAX(lfd) + 1 INTO @i FROM table1;

INSERT INTO table1 (lfd,col1,...)
SELECT @i:=@i+1,somedata,... FROM SomeTable;

本质上,这只是使用一个变量作为序列,使用表中当前的最大 id 对其进行初始化。

请注意,如果在此查询运行时将行插入table1,您可能会遇到并发问题。

【讨论】:

    【解决方案2】:

    只需将lfd 定义为autoincrement column。这样您就不必为select max(...) ... 操心了。

    这是一种不同的方法:

    insert into table1 (lfd, somedata)
    select 
      (
        select count(*) + (select count(*) from table1) 
        from table2 l
        where l.lfd <= r.lfd
      ),
      r.somedata
    from table2 r;
    

    这是如何工作的:

    1. table2 中的行从1 到n 排序(其中n 是table2 中的行数)
    2. 将初始 max(lfd) 添加到排名中,因此值将是唯一的

    注意事项:这是一个 n**2 查询,所以如果您有一个大数据集,这可能需要一段时间。

    【讨论】:

    • 感谢您的提示。遗憾的是,我无法触及表结构,因为我将数据从一个 php-gallery 迁移到另一个不同的 php-gallery。表的结构由应用程序控制。
    • @MattFenwick:我的错,我认为select .. from table1 子查询会弄乱它。但是,如果其他并发插入发生在table1 中,那么并发问题呢?可能会导致碰撞...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    相关资源
    最近更新 更多