所以我的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
答案 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个值,但原则是一样的。