Mysql go客户端中的select查询中的SQL变量未更新

Mysql go客户端中的select查询中的SQL变量未更新,mysql,sql,go,Mysql,Sql,Go,我正在SQL中运行以下查询 SET @thisid=0; SET @serial=0; SELECT @serial := IF((@thisid != `places`.`id`), @serial + 1, @serial) as `serial`, @thisid := `places`.`id`, `places`.`id` FROM `places`; 仅当新id与上一个id不同时,@serial变量基本上才会递增。 在终端中运行这些查询并打印@serial和@thisid的值时,

我正在SQL中运行以下查询

SET @thisid=0;
SET @serial=0;

SELECT @serial := IF((@thisid != `places`.`id`), @serial + 1, @serial) as `serial`, @thisid := `places`.`id`, `places`.`id` FROM `places`;
仅当新id与上一个id不同时,@serial变量基本上才会递增。 在终端中运行这些查询并打印@serial和@thisid的值时,收到的值为@thisid='id6'@serial=6

我在我的go代码中执行了此查询:

if _, err = repo.db.ExecContext(ctx, "SET @thisid=0;"); err != nil {
    return
}

if _, err = repo.db.ExecContext(ctx, "SET @serial=0;"); err != nil {
    return
}

rows, err = repo.db.QueryContext(ctx, fmt.Sprintf(
    "SELECT @serial := IF((@thisid != `places`.`id`), @serial + 1, @serial) as `serial`, @thisid := `places`.`id`, `places`.`id` FROM `places`;",
))
if err != nil {
    fmt.Println("error here")
    return
}

if err = repo.db.QueryRow("SELECT @serial").Scan(&that); err != nil {
    return
}

if err = repo.db.QueryRow("SELECT @thisid").Scan(&this); err != nil {
    return
}

打印@thisid和@serial的值时,接收到的@thisid值与接收到的@serial值为0时相同。它似乎不会动态更新。

您的查询确实是任意的。MySQL不保证
select
中表达式的求值顺序。它也不能保证结果集的顺序

所以,我想你想要:

select p.*,
       (@rn := if(@id = id, @rn + 1,
                  if(@id := id, 1, 1)
                 )
       ) as serial
from (select p.*
      from places p
      order by p.id
     ) p cross join
     (select @id := 0, @rn := 0) params;

你的查询很随意。MySQL不保证
select
中表达式的求值顺序。它也不能保证结果集的顺序

所以,我想你想要:

select p.*,
       (@rn := if(@id = id, @rn + 1,
                  if(@id := id, 1, 1)
                 )
       ) as serial
from (select p.*
      from places p
      order by p.id
     ) p cross join
     (select @id := 0, @rn := 0) params;

Go使用连接池,这意味着每个查询可能发生在不同的连接上。这样的变量的作用域是连接。如果您需要它们在两次查询之间持续,则需要使用事务来确保您保持在同一连接中。

Go使用连接池,这意味着每个查询可能发生在不同的连接上。这样的变量的作用域是连接。如果您需要它们在两次查询之间持续,则需要使用事务来确保您保持在同一个连接中。

Go使用连接池,这意味着每个查询可能发生在不同的连接上。这样的变量的作用域是连接。如果您需要它们在两次查询之间持续,则需要使用事务来确保您保持在相同的连接中。@Flimzy谢谢您解决了这个问题。如果您愿意回答,那么我会选择您的作为最佳答案。Go使用连接池,这意味着每个查询可能发生在不同的连接上。这样的变量的作用域是连接。如果您需要它们在两次查询之间持续,则需要使用事务来确保您保持在相同的连接中。@Flimzy谢谢您解决了这个问题。如果你愿意回答,那么我会选择你的作为最佳答案。我想要的答案是评论。但不对子查询结果排序的事实解决了我的另一个问题。谢谢我想要的答案是评论。但不对子查询结果排序的事实解决了我的另一个问题。谢谢