golang mysql在结构中存储了任意数量的行

时间:2014-06-25 17:56:18

标签: mysql go

所以我的sql看起来像这样

SELECT accounts.id, accounts.username, accounts.password, 
      accounts.created, accounts.last_logged_in, accounts.access,
      banned.reason, banned.expires,
      player.x, player.y, player.zone
FROM accounts
LEFT JOIN banned
ON accounts.id = banned.account_Id
INNER JOIN player
ON accounts.id = player.account_Id
WHERE accounts.username = username

如果我想将它存储在一个结构中,我通常会这样做:

type Account struct {
    Id           int
    Username     string
    Password     string
    Email        string
    Created      time.Time
    LastLoggedIn time.Time
    AccessLevel  int
    Location     struct {
        Zone string
    }
    Banned []*Banned
}

type Banned struct {
    Reason  string
    Expires time.Time
}
reply := new(Account)

stmt, err := this.Database.Prepare(("CALL findUser(?)"))
    defer stmt.Close()

if err != nil {
    logger.ERROR.Println(err)
    return err
}

err = stmt.QueryRow(args).Scan(&reply.Id, &reply.Username ... you get the idea)

然而这不起作用,因为扫描会期望每个参数都有一个值,而我们已经加入了被禁止的行列!因为用户可能有0 - N禁止什么是解决这个问题的最佳方法?

非常感谢 Zidsal

1 个答案:

答案 0 :(得分:2)

我觉得你的例子或问题不是你真正想描述的,因为他们并没有真正提出同样的问题。

阅读提供的示例,您有两种不同的类型要扫描(Account,左连接Banned),将对结果的每一行重复这些类型。因此,您只需要在Banned结构的同时创建一个新的Account结构,并使用它来扫描值,然后将其添加到Account.Banned切片。每行循环,你就完成了。

阅读你的问题,我认为你的SQL查询有些错误:你有多个帐户每个都有几个禁止,你想拥有一个帐户结果排在每一个禁令中。要做到这一点,您需要使用GROUP BY语句调整查询以按帐户获取一行,然后最明智的方法是执行GROUP_CONCAT以将每个禁令都放入一个属性中然后解析。示例(过度简化以更好地揭示原则):

  SELECT accounts.id, GROUP_CONCAT(banned.id SEPARATOR ',') as bans
  FROM accounts
  LEFT JOIN banned
  ON accounts.id = banned.account_Id
  WHERE accounts.username = username
  GROUP BY accounts.id

您只需将bans列扫描到一个字符串,将其拆分为,等。在您的情况下,解析将更复杂,因为您需要在一列中包含2个值,但原则是一样的。