所以我有这样的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
如果我想将其存储在 go 中的结构中,我通常会这样做:
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)
然而这是行不通的,因为 scan 会期望每个参数都有一个值,而我们已经加入到 banned 中了!由于用户可能有 0 - N 条禁令,解决此问题的最佳方法是什么?
非常感谢 齐萨尔
最佳答案
我觉得您的示例或问题都不是您真正想要描述的内容,因为它们并不是真正要求相同的问题。
阅读提供的示例,您有两种不同的类型要扫描(一个 Account
,左连接一个 Banned
),结果的每一行都会重复.因此,您只需在 Account
结构的同时创建一个新的 Banned
结构,并使用它来扫描值,然后将其添加到 Account。禁止
slice 。循环每一行,你就完成了。
阅读您的问题后,我认为您的 sql 查询有些错误:您有多个帐户,每个帐户都有多个ban,并且您希望拥有一个帐户结果行中包含每个禁令。为此,您需要使用 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个值,但原理是一样的。
关于mysql - golang mysql在结构中存储任意行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24415428/